如何在Django的管理界面中覆盖help_text?

14
我有多个管理站点,不同的用户在编辑数据库中的对象时会得到不同的体验。每个管理员站点都有不同的暴露对象集和不同的样式。可以通过覆盖模板和ModelAdmin对象完成所有这些操作。
我无法弄清如何在不同的站点中提供不同的help_texthelp_text总是直接从模型字段定义中获取,似乎没有办法进行覆盖。
我是否遗漏了什么,还是这是不可能的?
7个回答

17

您可以创建一个新的模型表单,并在那里覆盖help_text:

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['myfield'].help_text = 'New help text!'

然后在您的ModelAdmin中使用新表单:

class MyModel(admin.ModelAdmin):
     ...
     form = MyForm

这是更干净的方法,因为表单字段本来就属于表单!


1
奇怪的是,这似乎无法与editable=False字段一起使用。这些字段甚至不会出现在表单字段中... - Cerin
你好@Cerin,是的,你说得对,只读字段始终从管理模型表单中排除。它们不是只读/禁用表单输入或类似的东西,而是模型字段或方法的str表示形式。 - ppetrid

10

另一种方法是通过将 help_texts 关键字传递给 get_form 方法,像这样:

def get_form(self, *args, **kwargs):
    help_texts = {'my_field': 'Field explanation'}
    kwargs.update({'help_texts': help_texts})
    return super().get_form(*args, **kwargs)
help_texts关键字最终传递给modelform_factory方法,并在Django管理界面中呈现为来自模型的标准帮助文本。
如果您正在使用InlineModelAdmin,则需要以相同的方式覆盖get_formset
如果您的ModelAdmin子类中有readonly_fields,这也适用。

1
实际上,我尝试了上述方法,这是唯一一个与readonly_fields一起使用的方法。原因是Django表单对象不处理readonly_fields,所以当您尝试self.fields['my_field'].help_text =时,您只会得到一个KeyError。 - pandichef
这也适用于模型中不存在的自定义字段。 - Erik Kalkoken

8
在Django 1.9中,与下面类似的内容适用于我。
def get_form(self, request, obj=None, **kwargs):
    form = super(MyAdmin, self).get_form(request, obj, **kwargs)
    form.base_fields['my_field'].help_text = """
    Some helpful text
    """
    return form

这是一个有用且快速的方法来完成它! - Ícaro

1
Cerin 是对的,但他的代码在 Django 1.4 中效果不佳。
def get_readonly_fields(self, request, obj):
    try:
        field = [f for f in obj._meta.fields if f.name == 'author']
        if len(field) > 0:
            field = field[0]
            field.help_text = 'some special help text'
    except:
        pass
    return self.readonly_fields

您需要根据自己的需求更改“作者”和help_text字符串。


0
如果您只在admin.py中定义了自定义字段,并且该字段不在您的模型中,则可以使用自定义ModelFormclass Meta添加help_text
(例如:您想在表单上添加用户照片,您可以定义一个自定义html img标签像这样。)
class SomeModelForm(forms.ModelForm):
    # You don't need to define a custom form field or setup __init__()

    class Meta:
        model = SomeModel
        help_texts = {"avatar": "User's avatar Image"}


# And tell your admin.py to use the ModelForm:
class SomeModelAdmin(admin.ModelAdmin):
    form = SomeModelForm
    
    # ... rest of the code

这种方法似乎不再起作用了。我收到了这个错误:django.core.exceptions.ImproperlyConfigured: 禁止创建没有'fields'属性或'exlude'属性的ModelForm;需要更新OwnerForm表单。 - Erik Kalkoken
@ErikKalkoken 这是一个不同的错误。您可以轻松地向您的类Meta添加一个“exclude”或“fields”属性,就像这样:https://docs.djangoproject.com/en/3.2/topics/forms/modelforms/#selecting-the-fields-to-use - Nitin Nain

0

您可以在ModelAdmin构造函数中随时更改表单字段属性,例如:

    def __init__(self, *args, **kwargs):
        super(ClassName, self).__init__(*args, **kwargs)
        if siteA:
            help_text = "foo"
        else:
            help_text = "bar"
        self.form.fields["field_name"].help_text = help_text

据我所见,似乎不起作用 - ModelAdmin.fields 只是一个字符串列表:http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fields - Toby
糟糕!实际上,字段将通过ModelAdmin的表单属性可用。此外,请确保首先调用父构造函数。请参见编辑。 - Carlos H Romano
仍然对我不起作用:"type object 'ModelForm'没有'fields'属性"。 - Toby
我也遇到了同样的错误。你找到解决方法了吗?我也尝试重写ModelAdmin的get_form()方法并操作字段,但没有成功。 - onurmatik

-1

试试这个(可能需要将self.fields替换为self.form.fields...)

class PropertyForm(models.ModelAdmin):
    class Meta:
        model = Property
    def __init__(self, *args, **kwargs):
        super(PropertyForm, self).__init__(*args, **kwargs)
        for (key, val) in self.fields.iteritems():
            self.fields[key].help_text = 'what_u_want' 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接