我想在django管理站点中更改myfield
字段的默认小部件。我需要一个select
小部件而不是input
。该代码工作正常:
admin.py:
from django.contrib import admin
from django import forms
from .models import MyModel
CHOICES = (
("hello", "hello"),
("world", "world")
)
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
print("Raised: ", db_field, kwargs['request'])
if db_field.name == 'myfield':
kwargs['widget'] = forms.Select(choices=CHOICES)
return super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
admin.site.register(MyModel, MyModelAdmin)
models.py:
from django.db import models
class MyModel(models.Model):
myfield = models.CharField(max_length=255)
但是有一个问题。添加/编辑页面打开时,formfield_for_dbfield
函数会多次引发。单个GET请求有一个日志条目:
...
[22/Dec/2015 17:16:34] "GET /static/admin/js/vendor/xregexp/xregexp.min.js HTTP/1.1" 200 62474
[22/Dec/2015 17:16:34] "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 200 331
Raised: testapp.MyModel.id <WSGIRequest: GET '/admin/testapp/mymodel/add/'>
Raised: testapp.MyModel.myfield <WSGIRequest: GET '/admin/testapp/mymodel/add/'>
Raised: testapp.MyModel.myfield <WSGIRequest: GET '/admin/testapp/mymodel/add/'>
Raised: testapp.MyModel.id <WSGIRequest: GET '/admin/testapp/mymodel/add/'>
Raised: testapp.MyModel.myfield <WSGIRequest: GET '/admin/testapp/mymodel/add/'>
[22/Dec/2015 17:16:39] "GET /admin/testapp/mymodel/add/ HTTP/1.1" 200 5433
[22/Dec/2015 17:16:39] "GET /static/admin/css/forms.css HTTP/1.1" 200 7750
...
有五次致电formfield_for_db_field
,其中三次与myfield
有关。为什么会这样?我的项目中有一个可调用的方法而不是CHOICES,所以我不想在每个请求的结果中多次提出它。
答案 0 :(得分:0)
我找到了更准确的方法来获取此行为。关键是使用带有覆盖from django.contrib import admin
from django.forms import ModelForm, Select
from .models import MyModel
CHOICES = (
("hello", "hello"),
("world", "world")
)
class MyModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
self.fields['myfield'].widget = Select(choices=CHOICES)
class Meta:
model = MyModel
fields = ('myfield',)
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
admin.site.register(MyModel, MyModelAdmin)
方法的自定义表单,因此所有字段都可以即时修改,每个请求只能修改一次。这是admin.py的更新版本:
CHOICES
module = Extension("temp", "temp.pyx")
module.cython_c_in_temp = True
变量可以被函数替换,并且此函数只会被调用一次。