Image model 代码如下
# cat app/models/image.rb
class Image < ActiveRecord::Base
has_attached_file :data,
:url => "/system/images/:id/:style_:basename.:extension",
:path => ":rails_root/public/system/images/:id/:style_:basename.:extension",
:styles => { :normal => ['400x300#', :png], :thumb => ['200x150#', :png] }
validates_attachment_size :data, :less_than => 2.megabytes
validates_attachment_presence :data
end
那么想在 seed 中保存几个图片到 Image,就这样写
# cat db/seeds.rb
#first, add gem "content_type" to Gemfile and bundle install, http://rubygems.org/gems/content_type
attachment_file = "#{Rails.root}/public/images/rails.png"
attachment = {
:original_filename => File.basename(attachment_file),
:content_type => File.content_type(attachment_file),
:tempfile => File.open(attachment_file, 'rb')
}
data_obj = ActionDispatch::Http::UploadedFile.new(attachment)
data_obj.original_filename = attachment[:original_filename]
data_obj.content_type = attachment[:content_type]
Image.create!(:data => data_obj)
后记:
使用 fixture_file_upload
include ActionDispatch::TestProcess
Image.create :data => fixture_file_upload("/root/profile.jpg", 'image/jpg')
结合 factory_girl 使用如下
include ActionDispatch::TestProcess
FactoryGirl.define do
factory :attachment do
name { Faker::LoremCN.word }
describtion { Faker::LoremCN.word }
data { fixture_file_upload(Rails.root.join('public', 'images', 'rails.png'), 'image/png', :binary) }
download_times { rand 1_000 }
end
end
# cat app/models/image.rb
class Image < ActiveRecord::Base
has_attached_file :data,
:url => "/system/images/:id/:style_:basename.:extension",
:path => ":rails_root/public/system/images/:id/:style_:basename.:extension",
:styles => { :normal => ['400x300#', :png], :thumb => ['200x150#', :png] }
validates_attachment_size :data, :less_than => 2.megabytes
validates_attachment_presence :data
end
那么想在 seed 中保存几个图片到 Image,就这样写
# cat db/seeds.rb
#first, add gem "content_type" to Gemfile and bundle install, http://rubygems.org/gems/content_type
attachment_file = "#{Rails.root}/public/images/rails.png"
attachment = {
:original_filename => File.basename(attachment_file),
:content_type => File.content_type(attachment_file),
:tempfile => File.open(attachment_file, 'rb')
}
data_obj = ActionDispatch::Http::UploadedFile.new(attachment)
data_obj.original_filename = attachment[:original_filename]
data_obj.content_type = attachment[:content_type]
Image.create!(:data => data_obj)
后记:
使用 fixture_file_upload
include ActionDispatch::TestProcess
Image.create :data => fixture_file_upload("/root/profile.jpg", 'image/jpg')
结合 factory_girl 使用如下
include ActionDispatch::TestProcess
FactoryGirl.define do
factory :attachment do
name { Faker::LoremCN.word }
describtion { Faker::LoremCN.word }
data { fixture_file_upload(Rails.root.join('public', 'images', 'rails.png'), 'image/png', :binary) }
download_times { rand 1_000 }
end
end
类别:ruby & rails | Tags: 原创 , 代码 , 图片处理 , 学习笔记 , gem , model , orm , paperclip , activerecord | 0 条评论, 2744 次阅读
Jun
6
2011
这个 rake 主要用来在rails中自动生成 config/locales/zh-CN.model.yml ,建好model后执行一下,主要为了提高工作效率用,写的比较简陋,呵呵,凑合着用哈先
#encoding: utf-8
#
# by: vkill vkill.net@gmail.com
# updated_at: 2011.6.6
# first, please install psych gem, YAML dump support Chinese
#
# usage:
# write it to Rails.root.join("lib/tasks/model_i18n_column.rake")
# >rake model:i18n_column
#
require 'find'
require 'fileutils'
require 'tmpdir'
namespace :model do
desc 'this is auto generate i18n.zh-CN.activerecord'
task :i18n_column => :environment do
t = {
"id" => '序号',
"type" => '类型',
"name" => '名称',
"state" => '状态',
"title" => '标题',
"content" => '正文',
"created_at" => '创建时间',
"updated_at" => '更新时间',
"user_id" => '用户id'
}
i18n_new = {
"zh-CN" => {
"activemodel" => {
"models" => {},
"attributes" => {}
},
"activerecord" => {
"models" => {},
"attributes" => {}
}
}
}
i18n_file = Rails.root.join("config/locales/zh-CN.model.yml").to_s
i18n_tmp = File.join(Dir.tmpdir, File.basename(i18n_file) + "_" + Time.now.strftime('%Y%m%d%H%M%S'))
i18n = YAML.load_file(i18n_file) || i18n_new
Find.find(Rails.root.join("app/models").to_s) do |path|
if FileTest.directory?(path)
if File.basename(path)[0] == ?.
Find.prune
else
next
end
else
require path
end
end
ObjectSpace.each_object(Class) do |k|
if k.ancestors.include?(ActiveRecord::Base)
if k.name != "ActiveRecord::Base" and !k.abstract_class?
if k.table_exists?
if k.column_names.include?('type') and k.subclasses.size > 0
next
end
#puts k.name
model = k.name.underscore
i18n_new["zh-CN"]["activerecord"]["models"][model] = i18n["zh-CN"]["activerecord"]["models"][model] || model
i18n_new["zh-CN"]["activerecord"]["attributes"][model] = i18n["zh-CN"]["activerecord"]["attributes"][model] || {}
k.column_names.each do |column|
if !i18n_new["zh-CN"]["activerecord"]["attributes"][model][column]
i18n_new["zh-CN"]["activerecord"]["attributes"][model][column] = t[column.to_s] || column.to_s
end
end
if enums = i18n["zh-CN"]["activerecord"]["attributes"][model]["enums"]
i18n_new["zh-CN"]["activerecord"]["attributes"][model]["enums"] = enums
end
end
end
end
end
FileUtils.cp(i18n_file, i18n_tmp)
require 'psych'
require 'yaml'
YAML::ENGINE.yamler= 'psych'
File.open(i18n_file, "wb") do |f|
f.write YAML.dump(i18n_new)
end
YAML::ENGINE.yamler= 'syck'
puts "updated #{i18n_file}, old file backup to #{i18n_tmp}"
end
end
2011.12.1 更新:
有个更好的方法,参见 https://github.com/vkill/i18n_attributes 这个gem
#encoding: utf-8
#
# by: vkill vkill.net@gmail.com
# updated_at: 2011.6.6
# first, please install psych gem, YAML dump support Chinese
#
# usage:
# write it to Rails.root.join("lib/tasks/model_i18n_column.rake")
# >rake model:i18n_column
#
require 'find'
require 'fileutils'
require 'tmpdir'
namespace :model do
desc 'this is auto generate i18n.zh-CN.activerecord'
task :i18n_column => :environment do
t = {
"id" => '序号',
"type" => '类型',
"name" => '名称',
"state" => '状态',
"title" => '标题',
"content" => '正文',
"created_at" => '创建时间',
"updated_at" => '更新时间',
"user_id" => '用户id'
}
i18n_new = {
"zh-CN" => {
"activemodel" => {
"models" => {},
"attributes" => {}
},
"activerecord" => {
"models" => {},
"attributes" => {}
}
}
}
i18n_file = Rails.root.join("config/locales/zh-CN.model.yml").to_s
i18n_tmp = File.join(Dir.tmpdir, File.basename(i18n_file) + "_" + Time.now.strftime('%Y%m%d%H%M%S'))
i18n = YAML.load_file(i18n_file) || i18n_new
Find.find(Rails.root.join("app/models").to_s) do |path|
if FileTest.directory?(path)
if File.basename(path)[0] == ?.
Find.prune
else
next
end
else
require path
end
end
ObjectSpace.each_object(Class) do |k|
if k.ancestors.include?(ActiveRecord::Base)
if k.name != "ActiveRecord::Base" and !k.abstract_class?
if k.table_exists?
if k.column_names.include?('type') and k.subclasses.size > 0
next
end
#puts k.name
model = k.name.underscore
i18n_new["zh-CN"]["activerecord"]["models"][model] = i18n["zh-CN"]["activerecord"]["models"][model] || model
i18n_new["zh-CN"]["activerecord"]["attributes"][model] = i18n["zh-CN"]["activerecord"]["attributes"][model] || {}
k.column_names.each do |column|
if !i18n_new["zh-CN"]["activerecord"]["attributes"][model][column]
i18n_new["zh-CN"]["activerecord"]["attributes"][model][column] = t[column.to_s] || column.to_s
end
end
if enums = i18n["zh-CN"]["activerecord"]["attributes"][model]["enums"]
i18n_new["zh-CN"]["activerecord"]["attributes"][model]["enums"] = enums
end
end
end
end
end
FileUtils.cp(i18n_file, i18n_tmp)
require 'psych'
require 'yaml'
YAML::ENGINE.yamler= 'psych'
File.open(i18n_file, "wb") do |f|
f.write YAML.dump(i18n_new)
end
YAML::ENGINE.yamler= 'syck'
puts "updated #{i18n_file}, old file backup to #{i18n_tmp}"
end
end
2011.12.1 更新:
有个更好的方法,参见 https://github.com/vkill/i18n_attributes 这个gem
Jun
6
2011
django 一对多 多外键的用法
09:38 , vkill
下面这个例子是 人员表和任务表,人员表和任务表是一对多的,但是这里有 分配任务的人 和 接受任务的人,所以这里就要用到 一对多 多外键
下面是 models.py 的代码及例子
class Person(models.Model):
name = models.CharField(max_length=50)
class Task(models.Model):
assign = models.ForeignKey(Person,related_name='assign')
accept = models.ForeignKey(Person,related_name='accept')
#use
>>> Person.objects.create(name='a')
<Person: Person object>
>>> Person.objects.create(name='b')
<Person: Person object>
>>> Person.objects.create(name='c')
<Person: Person object>
>>> Person.objects.create(name='d')
<Person: Person object>
>>> Task.objects.create(assign_id=1,accept_id=2)
<Task: Task object>
>>> Task.objects.create(assign_id=1,accept_id=3)
<Task: Task object>
>>> Task.objects.create(assign_id=1,accept_id=4)
<Task: Task object>
>>> Task.objects.create(assign_id=2,accept_id=3)
<Task: Task object>
>>> Task.objects.create(assign_id=2,accept_id=4)
<Task: Task object>
>>> Person.objects.get(name='b').assign.all()
[<Task: Task object>, <Task: Task object>]
>>> Person.objects.get(name='b').accept.all()
[<Task: Task object>]
>>> Task.objects.get(pk=1).assign.name
u'a'
>>> Task.objects.get(pk=1).accept.name
u'b'
下面是 models.py 的代码及例子
class Person(models.Model):
name = models.CharField(max_length=50)
class Task(models.Model):
assign = models.ForeignKey(Person,related_name='assign')
accept = models.ForeignKey(Person,related_name='accept')
#use
>>> Person.objects.create(name='a')
<Person: Person object>
>>> Person.objects.create(name='b')
<Person: Person object>
>>> Person.objects.create(name='c')
<Person: Person object>
>>> Person.objects.create(name='d')
<Person: Person object>
>>> Task.objects.create(assign_id=1,accept_id=2)
<Task: Task object>
>>> Task.objects.create(assign_id=1,accept_id=3)
<Task: Task object>
>>> Task.objects.create(assign_id=1,accept_id=4)
<Task: Task object>
>>> Task.objects.create(assign_id=2,accept_id=3)
<Task: Task object>
>>> Task.objects.create(assign_id=2,accept_id=4)
<Task: Task object>
>>> Person.objects.get(name='b').assign.all()
[<Task: Task object>, <Task: Task object>]
>>> Person.objects.get(name='b').accept.all()
[<Task: Task object>]
>>> Task.objects.get(pk=1).assign.name
u'a'
>>> Task.objects.get(pk=1).accept.name
u'b'
May
30
2011
这里不是说的是 profile,关于 profile 的看官方
网上有继承 User 的那个更不可用
django 写的太死,扩展下还是很麻烦
还有,下面的这个会在 django 库的 contrib\auth 目录下创建 migrations 目录,如果你觉得这个影响你别的项目的话,那就在这个项目目录下新建 django 目录,把 django 库下的文件全部复制过来,目录结构如 项目目录/django/bin 这样
------------------------------------------------------
后记:
south 的 auth migrations 目录可以定义的,方法来自于 django-primate 这个app
#注意,这里你要在项目目录下建个 users 目录
SOUTH_MIGRATION_MODULES = {
'auth': 'users.migrations',
}
还有,更好的扩展 User model 使用 django-primate 这个库要好很多,参见 https://github.com/aino/django-primate
------------------------------------------------------
开工
F:\hyp\test>django-admin.py startproject my_django
F:\hyp\test>cd my_django
F:\hyp\test\my_django>manage.py startapp my_app
编辑 settings.py,INSTALLED_APPS 加入 my_app 和 south ,如下
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'my_app',
'south'
)
DATABASES 配置好引擎并建好数据库,如这里我们配置成sqlite3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'test.db', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
my_app/models.py 中加入,添加一个字段,添加一个实例方法,一个类方法
关于添加字段参见 http://djangosnippets.org/snippets/2132/
from django.db import models
from django.contrib.auth.models import User
some_field = models.CharField(max_length=32)
some_field.contribute_to_class(User, 'some_field')
def before_save(self):
self.username = 'test'
User.before_save = before_save
@classmethod
def test(cls):
print cls.__name__
User.test = test
创建 auth 的 migration,这样在 syncdb 的时候就会跳过 auth 这个app
F:\hyp\test\my_django>manage.py schemamigration auth --initial
Creating migrations directory at 'F:\hyp\language\Python27\lib\site-packages\django\contrib\auth\migrations'...
Creating __init__.py in 'F:\hyp\language\Python27\lib\site-packages\django\contrib\auth\migrations'...
+ Added model auth.Permission
+ Added unique constraint for ['content_type', 'codename'] on auth.Permission
+ Added model auth.Group
+ Added M2M table for permissions on auth.Group
+ Added model auth.User
+ Added M2M table for groups on auth.User
+ Added M2M table for user_permissions on auth.User
+ Added model auth.Message
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate auth
创建 my_app 的 migration
F:\hyp\test\my_django>manage.py schemamigration my_app --initial
Creating migrations directory at 'F:\hyp\test\my_django\my_app\migrations'...
Creating __init__.py in 'F:\hyp\test\my_django\my_app\migrations'...
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate my_app
执行 manage.py syncdb --all 创建表
F:\hyp\test\my_django>manage.py syncdb --all
Syncing...
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table south_migrationhistory
You just installed Django's auth system, which means you don't have any superuse
rs defined.
Would you like to create one now? (yes/no): no
Installing custom SQL ...
Installing indexes ...
No fixtures found.
Synced:
> django.contrib.auth
> django.contrib.contenttypes
> django.contrib.sessions
> django.contrib.sites
> django.contrib.messages
> django.contrib.staticfiles
> my_app
> south
Not synced (use migrations):
-
(use ./manage.py migrate to migrate these)
好了,基本上搞定了,下面我们来测试一下
F:\hyp\test\my_django>manage.py shell
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from my_app.models import *
>>> u = User()
>>> u.username
''
>>> u.before_save()
>>> u.username
'test'
>>> u.some_field
''
>>> User.test()
User
网上有继承 User 的那个更不可用
django 写的太死,扩展下还是很麻烦
还有,下面的这个会在 django 库的 contrib\auth 目录下创建 migrations 目录,如果你觉得这个影响你别的项目的话,那就在这个项目目录下新建 django 目录,把 django 库下的文件全部复制过来,目录结构如 项目目录/django/bin 这样
------------------------------------------------------
后记:
south 的 auth migrations 目录可以定义的,方法来自于 django-primate 这个app
#注意,这里你要在项目目录下建个 users 目录
SOUTH_MIGRATION_MODULES = {
'auth': 'users.migrations',
}
还有,更好的扩展 User model 使用 django-primate 这个库要好很多,参见 https://github.com/aino/django-primate
------------------------------------------------------
开工
F:\hyp\test>django-admin.py startproject my_django
F:\hyp\test>cd my_django
F:\hyp\test\my_django>manage.py startapp my_app
编辑 settings.py,INSTALLED_APPS 加入 my_app 和 south ,如下
Quotation
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'my_app',
'south'
)
DATABASES 配置好引擎并建好数据库,如这里我们配置成sqlite3
Quotation
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'test.db', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
my_app/models.py 中加入,添加一个字段,添加一个实例方法,一个类方法
关于添加字段参见 http://djangosnippets.org/snippets/2132/
from django.db import models
from django.contrib.auth.models import User
some_field = models.CharField(max_length=32)
some_field.contribute_to_class(User, 'some_field')
def before_save(self):
self.username = 'test'
User.before_save = before_save
@classmethod
def test(cls):
print cls.__name__
User.test = test
创建 auth 的 migration,这样在 syncdb 的时候就会跳过 auth 这个app
F:\hyp\test\my_django>manage.py schemamigration auth --initial
Creating migrations directory at 'F:\hyp\language\Python27\lib\site-packages\django\contrib\auth\migrations'...
Creating __init__.py in 'F:\hyp\language\Python27\lib\site-packages\django\contrib\auth\migrations'...
+ Added model auth.Permission
+ Added unique constraint for ['content_type', 'codename'] on auth.Permission
+ Added model auth.Group
+ Added M2M table for permissions on auth.Group
+ Added model auth.User
+ Added M2M table for groups on auth.User
+ Added M2M table for user_permissions on auth.User
+ Added model auth.Message
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate auth
创建 my_app 的 migration
F:\hyp\test\my_django>manage.py schemamigration my_app --initial
Creating migrations directory at 'F:\hyp\test\my_django\my_app\migrations'...
Creating __init__.py in 'F:\hyp\test\my_django\my_app\migrations'...
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate my_app
执行 manage.py syncdb --all 创建表
F:\hyp\test\my_django>manage.py syncdb --all
Syncing...
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table south_migrationhistory
You just installed Django's auth system, which means you don't have any superuse
rs defined.
Would you like to create one now? (yes/no): no
Installing custom SQL ...
Installing indexes ...
No fixtures found.
Synced:
> django.contrib.auth
> django.contrib.contenttypes
> django.contrib.sessions
> django.contrib.sites
> django.contrib.messages
> django.contrib.staticfiles
> my_app
> south
Not synced (use migrations):
-
(use ./manage.py migrate to migrate these)
好了,基本上搞定了,下面我们来测试一下
F:\hyp\test\my_django>manage.py shell
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from my_app.models import *
>>> u = User()
>>> u.username
''
>>> u.before_save()
>>> u.username
'test'
>>> u.some_field
''
>>> User.test()
User
May
26
2011
更改 modelchoicefield 下拉里的内容
11:21 , vkill
官方文档:http://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield
默认的是显示 Model().__unicode__() 里的内容,下面几个位置都可以改,在任一一个地方改都可以
方法1:
class BookForm(ModelFormBase):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.fields['person'].queryset = Person.objects.all()
self.fields['person'].label_from_instance = lambda obj: "%s" % (obj.name)
class Meta:
model = Book
mytest = forms.CharField(max_length=5)
方法2:
from django.forms.models import ModelChoiceField
class PersonModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "%s" % obj.name
class BookForm(ModelFormBase):
class Meta:
model = Book
mytest = forms.CharField(max_length=5)
person = PersonModelChoiceField(queryset = Person.objects.all())
方法3:
class Person(ModelPerson, MPerson):
def __unicode__(self):
return "%s" % self.name
方法4:view中动态的更改
def create_book(request):
form = BookForm()
form.fields['category'].queryset = request.user.categories.all()
#form.base_fields['category'].queryset = request.user.categories.all()
ok了,具体的用哪个这个看需求,哈哈
默认的是显示 Model().__unicode__() 里的内容,下面几个位置都可以改,在任一一个地方改都可以
方法1:
class BookForm(ModelFormBase):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.fields['person'].queryset = Person.objects.all()
self.fields['person'].label_from_instance = lambda obj: "%s" % (obj.name)
class Meta:
model = Book
mytest = forms.CharField(max_length=5)
方法2:
from django.forms.models import ModelChoiceField
class PersonModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "%s" % obj.name
class BookForm(ModelFormBase):
class Meta:
model = Book
mytest = forms.CharField(max_length=5)
person = PersonModelChoiceField(queryset = Person.objects.all())
方法3:
class Person(ModelPerson, MPerson):
def __unicode__(self):
return "%s" % self.name
方法4:view中动态的更改
def create_book(request):
form = BookForm()
form.fields['category'].queryset = request.user.categories.all()
#form.base_fields['category'].queryset = request.user.categories.all()
ok了,具体的用哪个这个看需求,哈哈
May
19
2011
当我们在 类实例方法/类方法 中使用装饰器 cache_page 的时候,如下面这样
class PersonView(ViewBase):
@cache_page(60 * 15)
def index(self, request, *args, **kwargs):
persons = Person.objects.select_related()
return list_detail.object_list(
request,
queryset = persons,
template_name = "person/index.html",
paginate_by = 3,
extra_context = {'string':'aaa'}
)
此时就会提示下面这个错误
ViewClass instance has no attribute 'method'
发生在 Python27\lib\site-packages\django\middleware\cache.py in process_request, line 138
看了下位置意思是 request.method 这个错了
之前想过,django自带的那些装饰器都是针对 函数 的,而类实例方法多了个 self 参数,自然用django自带的那些会出错的,至少从理论上来说是这样
google 了,搜索到这篇文章
http://www.toddreed.name/content/django-view-class/
很巧妙的给django自带的装饰器外再套一层装饰器使用,这个方法很不错,哈哈
新定义的装饰器
def on_method(function_decorator):
def decorate_method(unbound_method):
def method_proxy(self, *args, **kwargs):
def f(*a, **kw):
return unbound_method(self, *a, **kw)
return function_decorator(f)(*args, **kwargs)
return method_proxy
return decorate_method
类实例方法中使用django自带装饰器
class PersonView(ViewBase):
@on_method(cache_page(60 * 15))
def index(self, request, *args, **kwargs):
persons = Person.objects.select_related()
return list_detail.object_list(
request,
queryset = persons,
template_name = "person/index.html",
paginate_by = 3,
extra_context = {'string':'aaa'}
)
这样就好了,继续使用类实例方法做view中,哈哈
class PersonView(ViewBase):
@cache_page(60 * 15)
def index(self, request, *args, **kwargs):
persons = Person.objects.select_related()
return list_detail.object_list(
request,
queryset = persons,
template_name = "person/index.html",
paginate_by = 3,
extra_context = {'string':'aaa'}
)
此时就会提示下面这个错误
Quotation
ViewClass instance has no attribute 'method'
发生在 Python27\lib\site-packages\django\middleware\cache.py in process_request, line 138
看了下位置意思是 request.method 这个错了
之前想过,django自带的那些装饰器都是针对 函数 的,而类实例方法多了个 self 参数,自然用django自带的那些会出错的,至少从理论上来说是这样
google 了,搜索到这篇文章
http://www.toddreed.name/content/django-view-class/
很巧妙的给django自带的装饰器外再套一层装饰器使用,这个方法很不错,哈哈
新定义的装饰器
def on_method(function_decorator):
def decorate_method(unbound_method):
def method_proxy(self, *args, **kwargs):
def f(*a, **kw):
return unbound_method(self, *a, **kw)
return function_decorator(f)(*args, **kwargs)
return method_proxy
return decorate_method
类实例方法中使用django自带装饰器
class PersonView(ViewBase):
@on_method(cache_page(60 * 15))
def index(self, request, *args, **kwargs):
persons = Person.objects.select_related()
return list_detail.object_list(
request,
queryset = persons,
template_name = "person/index.html",
paginate_by = 3,
extra_context = {'string':'aaa'}
)
这样就好了,继续使用类实例方法做view中,哈哈
May
18
2011




