如何使Django管理员为只读文本区域字段



在Django管理中,如果我有一个模型字段是TextField,并使用readonly_fields将其设置为只读,那么它在<p>标记中显示为文本。

我希望它仍然显示为textarea字段,但设置了disabled属性。

实现这一点最简单的方法是什么?

使用表单字段

   somefield = forms.CharField(
       widget=forms.TextInput(attrs={'readonly':'readonly'})
    )

有点晚了,但这里有一个想法(灵感来自@cinoch的答案和这个答案)对我来说很有用,代码最少:

  1. 不要TextField的名称添加到ModelAdmin子类中的readonly_fields(否则步骤2无效)

  2. 相反,do将以下内容添加到ModelAdmin子类中:

    formfield_overrides = {
        TextField: dict(widget=Textarea(attrs=dict(readonly=True)))
    }
    

注意,这需要一些进口:

from django.db.models import TextField
from django.forms import Textarea

TextField现在将在管理页面上显示为可滚动的Textarea,而不是纯文本,并且根据需要,其内容现在将是只读的。

不利的一面是,这适用于模型中的所有TextFields。如果这是一个问题,您可能应该使用@cinoch建议的自定义表单,并在此处或此处详细描述。

此外,如果ModelAdmin.has_change_permission()返回False,则此操作无效。

@alassdair的答案实际上相当聪明,但不幸的是,它没有提供一个例子。

以下是我根据readonly_fields的文档进行澄清的尝试。

假设一个这样的模型:

class MyModel(models.Model):
    my_textfield = models.TextField()

管理员可能是这样的,使用format_html创建一个只读文本区域:

class MyModelAdmin(admin.ModelAdmin):
    exclude = ['my_textfield']
    readonly_fields = ['display_my_textfield']
    
    @admin.display(description='my textfield')
    def display_my_textfield(self, obj):
        return format_html(
            '<textarea cols="40" rows="10" readonly>{}</textarea>',
            obj.my_textfield)

如果ModelAdmin.has_change_permission()返回False,这也适用。

readonly_fields可以采用方法名和字段名。您可以编写一个方法,在禁用的文本区域中呈现字段的值。

请确保从模型管理中排除该字段,因为它将不再位于readonly_fields中。

最新更新