Django Admin:仅为一个模型字段使用自定义小部件

时间:2010-11-14 07:36:37

标签: python django django-forms django-admin django-widget

我的模型中有DateTimeField字段。我想将它显示为Django管理站点中的复选框小部件。为此,我创建了一个自定义表单小部件。但是,我不知道如何将自定义小部件用于这一个字段。

Django documentation解释了如何为特定类型的所有字段使用自定义窗口小部件:

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

但这并不够精细。我想仅为一个字段更改它。

4 个答案:

答案 0 :(得分:119)

为您的ModelAdmin创建一个自定义ModelForm并将“小部件”添加到其Meta类中,如下所示:

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

完成!

这种文档非直观地放在ModelForm文档中,在管理员文档中没有提及。请参阅:Creating forms from models

答案 1 :(得分:31)

在深入研究adminmodel fieldform field代码后,我认为实现我想要的唯一方法是创建自定义模型字段:

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 smartypants有更好的解决方案。

答案 2 :(得分:16)

像这样覆盖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/

答案 3 :(得分:4)

Django的ModelAdmin.get_changelist_form(self,request,** kwargs)将针对list_editable的情况采取行动

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

  #just return the ModelForm class StopAdminForm
  def get_changelist_form(self, request, **kwargs):
        return StopAdminForm

请参阅Django Official documentation on this topic

我希望这会有所帮助