Django管理后台:为单一模型字段使用自定义小部件

78 投票
5 回答
62881 浏览
提问于 2025-04-16 07:03

我在我的模型里有一个叫做 DateTimeField 的字段。我想在Django的管理后台把它显示成一个复选框。为此,我创建了一个自定义的表单控件。但是,我不知道怎么只对这个字段使用我的自定义控件。

Django的文档 中,有说明如何对所有同类型的字段使用自定义控件:

class StopAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.DateTimeField: {'widget': ApproveStopWidget }
    }

不过,这样太笼统了。我只想改变一个字段的显示方式。

5 个回答

30

像这样重写 formfield_for_dbfield:

class VehicleAdmin(admin.ModelAdmin):
    search_fields = ["name", "colour"]

    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name == 'colour':
            kwargs['widget'] = ColourChooserWidget
        return super(VehicleAdmin, self).formfield_for_dbfield(db_field,**kwargs)

(感谢 http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-django-admin-using-newforms-admin/ )

36

经过对管理后台模型字段表单字段代码的深入研究,我认为实现我想要的功能唯一的方法就是创建一个自定义的模型字段:

models.py

from django.db import models
from widgets import ApproveStopWidget

class ApproveStopModelField(models.DateTimeField):
    pass

class Stop(models.model):
    # Other fields
    approve_ts = ApproveStopModelField('Approve place', null=True, blank=True)

admin.py

from widgets import ApproveStopWidget
from models import ApproveStopModelField

class StopAdmin(admin.ModelAdmin):
    formfield_overrides = {
        ApproveStopModelField: {'widget': ApproveStopWidget }
    }

这样就能完成我想要的功能。

目前我就不回答这个问题了,因为我有时会忽视一些显而易见的东西。也许有些Django高手会有更好的解决方案。

141

为你的 ModelAdmin 创建一个自定义的 ModelForm,并在它的 Meta 类中添加 'widgets',像这样:

class StopAdminForm(forms.ModelForm):
  class Meta:
    model = Stop
    widgets = {
      'field_name': ApproveStopWidget(),
    }
    fields = '__all__'

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

完成了!

关于这个内容的说明其实在 ModelForm 的文档里,虽然在管理文档中没有提到。你可以查看这个链接了解更多:从模型创建表单

撰写回答