Django Admin - 重载自定义表单字段的小部件

36 投票
4 回答
59852 浏览
提问于 2025-04-16 02:42

我有一个自定义的 TagField 表单字段。

class TagField(forms.CharField):
    def __init__(self, *args, **kwargs):
        super(TagField, self).__init__(*args, **kwargs)
        self.widget = forms.TextInput(attrs={'class':'tag_field'})

如上所示,它使用的是 TextInput 表单字段小部件。但在管理后台,我希望它能用 Textarea 小部件来显示。为此,有一个叫做 formfield_overrides 的钩子,但在这种情况下并没有起作用。

管理后台的声明是:

class ProductAdmin(admin.ModelAdmin):
    ...
    formfield_overrides = {
        TagField: {'widget': admin.widgets.AdminTextareaWidget},
    }

这对表单字段小部件没有任何影响,tags 仍然是用 TextInput 小部件来显示的。

任何帮助都非常感谢。

--
omat

4 个回答

7

对于某个特定的字段,而不是一类字段,我使用的是:

Django 2.1.7

class ProjectAdminForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = '__all__'
        widgets = {
            'project_description': forms.Textarea(attrs={'cols': 98})
        }
class ProjectAdmin(admin.ModelAdmin):
    form = ProjectAdminForm

谢谢你,@Murat Çorlu

43

从Django 1.2开始,你可以通过扩展一个叫做Meta的类来覆盖字段小部件,这个类是ModelForm的一部分:

from django import forms
from django.contrib import admin


class ProductAdminForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'  # edit: django >= 1.8
        widgets = {
            'tags': admin.widgets.AdminTextareaWidget
        }


class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

https://docs.djangoproject.com/en/stable/topics/forms/modelforms/#overriding-the-default-fields

52

Django的管理后台为很多字段使用了自定义的控件。要修改这些字段,你需要为ModelAdmin对象创建一个表单。

# forms.py

from django import forms
from django.contrib import admin

class ProductAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProductAdminForm, self).__init__(*args, **kwargs)
        self.fields['tags'].widget = admin.widgets.AdminTextareaWidget()

接着,在你的ModelAdmin对象中,你需要指定这个表单:

from django.contrib import admin
from models import Product
from forms import ProductAdminForm

class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

admin.site.register(Product, ProductAdmin)

你还可以在这个时候修改查询集:比如根据模型中的另一个字段来筛选对象(因为limit_choices_to无法处理这种情况)。

撰写回答