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

Bel*_*dez 58 python django django-forms django-admin django-widget

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

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

class StopAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.DateTimeField: {'widget': ApproveStopWidget }
    }
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*att 122

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

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm
Run Code Online (Sandbox Code Playgroud)

完成!

此文件是有点不直观地摆在的ModelForm文档,没有任何提及到它在管理文档中给出.请参阅:从模型创建表单

  • 这保证了一个downvote?请花点时间阅读"Vote Down"权限说明:http://stackoverflow.com/privileges/vote-down.我非常肯定我的答案不符合"明确而且可能危险不正确的答案". (8认同)
  • 从Django 1.8开始,你应该将`fields ='__ all __'`添加到`Meta`.视频http://stackoverflow.com/a/28306347/1161025. (8认同)
  • 不幸的是,这似乎只适用于主"编辑"页面,而不是列表显示,而`formfield_overrides`适用于两者. (4认同)
  • ...和`approve_ts`是什么意思?然后在下一个答案中重复。话题的问题,在Django源码中都没有。 (4认同)

Bel*_*dez 32

在深入了解管理员,模型字段表单域代码之后,我相信实现我想要的唯一方法是创建自定义模型字段:

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)
Run Code Online (Sandbox Code Playgroud)

admin.py

from widgets import ApproveStopWidget
from models import ApproveStopModelField

class StopAdmin(admin.ModelAdmin):
    formfield_overrides = {
        ApproveStopModelField: {'widget': ApproveStopWidget }
    }
Run Code Online (Sandbox Code Playgroud)

它完成了工作.

暂时,我会留下没有答案的问题,因为我有找不到明显问题的习惯.也许一些Django smartypants有更好的解决方案.

  • 对于那些想知道如何将它与South集成的人,这个例子所需的行是:`from south.modelsinspector import add_introspection_rule add_introspection_rules([],["^ appname\.models\.ApproveStopModelField"]) (3认同)

And*_*ker 18

像这样覆盖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)
Run Code Online (Sandbox Code Playgroud)

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

  • 尼斯.添加一个自定义的`ModelForm`来改变一个字段的小部件似乎对我来说太过分了. (5认同)

小智 5

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
Run Code Online (Sandbox Code Playgroud)

有关此主题,请参阅Django 官方文档

我希望这个能帮上忙