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

发布于 2024-10-01 20:20:11 字数 640 浏览 8 评论 0原文

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

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

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

但这还不够精细。我只想更改一个字段。

I have a DateTimeField field in my model. I wanted to display it as a checkbox widget in the Django admin site. To do this, I created a custom form widget. However, I do not know how to use my custom widget for only this one field.

The Django documentation explains how to use a custom widget for all fields of a certain type:

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

This is not granular enough though. I want to change it for only one field.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

焚却相思 2024-10-08 20:20:12

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

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

完成!

这方面的文档有点不直观地放置在 ModelForm 文档中,管理文档中没有提及它。请参阅:创建表单来自模型

Create a custom ModelForm for your ModelAdmin and add 'widgets' to its Meta class, like so:

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

Done!

Documentation for this is sort of non-intuitively placed in the ModelForm docs, without any mention to it given in the admin docs. See: Creating forms from models

吻安 2024-10-08 20:20:12

深入研究 admin 后,模型字段表单字段 代码,我相信执行我想要的操作的唯一方法是创建自定义模型字段:

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

After digging into the admin, model field and form field code, I believe the only way to carry out what I want is by creating a custom model 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 }
    }

It gets the job done.

For the time being, I'll leave the question unanswered because I have the habit of missing the obvious. Perhaps some Django smartypants has a better solution.

去了角落 2024-10-08 20:20:12

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

Override formfield_for_dbfield like thus:

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)

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

拒绝两难 2024-10-08 20:20:12

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 官方文档

我希望这会有所帮助

Django's ModelAdmin.get_changelist_form(self, request, **kwargs) will do the trick for the case of 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

Refer to Django Official documentation on this topic

I hope this will help

兔小萌 2024-10-08 20:20:12

您可以通过将小部件分配给自定义表单中的字段并将自定义表单分配给管理员来仅更改一个字段的小部件,如下所示:

# "admin.py"

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        widgets = {
          'price': PriceWidget(),
        }
        fields = '__all__'

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    form = ProductForm

You can change the widget for only one field by assigning your widget to a field in a custom form and assigning the custom form to an admin as shown below:

# "admin.py"

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        widgets = {
          'price': PriceWidget(),
        }
        fields = '__all__'

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    form = ProductForm
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文