django admin formfield_for_dbfield多次提升

时间:2015-12-22 18:11:24

标签: python django

我想在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,所以我不想在每个请求的结果中多次提出它。

1 个答案:

答案 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 变量可以被函数替换,并且此函数只会被调用一次。