Django Admin:仅对一个模型字段使用自定义小部件
Posted
技术标签:
【中文标题】Django Admin:仅对一个模型字段使用自定义小部件【英文标题】:Django Admin: Using a custom widget for only one model field 【发布时间】:2011-05-09 18:18:54 【问题描述】:我的模型中有一个DateTimeField 字段。我想在 Django 管理站点中将其显示为复选框小部件。为此,我创建了一个自定义表单小部件。但是,我不知道如何将我的自定义小部件用于仅这一字段。
Django documentation 解释了如何为特定类型的所有字段使用自定义小部件:
class StopAdmin(admin.ModelAdmin):
formfield_overrides =
models.DateTimeField: 'widget': ApproveStopWidget
但这还不够精细。我只想为 一个 字段更改它。
【问题讨论】:
有一个更清晰的解决方案,使用Meta属性,这里:***.com/a/10293970 【参考方案1】:为您的 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
【讨论】:
不幸的是,这似乎只适用于主“编辑”页面,而不是列表显示,而formfield_overrides
两者都适用。
这值得否决?请花点时间阅读“投票否决”特权说明:***.com/privileges/vote-down。我很肯定我的答案不符合“一个明显不正确且可能危险地不正确的答案”。
意见不一:meta.stackexchange.com/a/112664/146243、meta.stackexchange.com/a/46590/146243、meta.stackexchange.com/a/46596/146243。
从 Django 1.8 开始,您应该将 fields = '__all__'
添加到 Meta
。视频***.com/a/28306347/1161025.
... 和approve_ts
是什么意思?然后在下一个答案中重复。 Django 源代码中没有这样的东西,无论是在主题的问题中。【参考方案2】:
在深入研究admin、model field 和form 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 有更好的解决方案。
【讨论】:
对于那些想知道如何将其与 South 集成的人,此示例所需的行是:from south.modelsinspector import add_introspection_rule add_introspection_rules([], ["^appname\.models\.ApproveStopModelField"])
【参考方案3】:
像这样覆盖 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/)
【讨论】:
不错。添加自定义ModelForm
来更改一个字段的小部件对我来说似乎有点过头了。
刚刚在 Django 1.11.5 中尝试过,效果很好。我的模型有多个 TextField,在 Admin 更改表单中,我需要一些是常规的 【参考方案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
我希望这会有所帮助
【讨论】:
以上是关于Django Admin:仅对一个模型字段使用自定义小部件的主要内容,如果未能解决你的问题,请参考以下文章
在我更改了一些模型字段(Django)之后,尝试访问 django admin 时出现 /admin/myapp/mymodel 的 TypeError
模型形式中的 django auto slug,例如 django admin 中的预填充字段