Django admin:将必填字段设为只读

TAH*_*TAH 0 django django-admin

我有许多与模型具有ForeignKey关系的Person模型.例如:

class PersonData(BaseModel):
    person = models.ForeignKey(Person)
    data = models.TextField()
Run Code Online (Sandbox Code Playgroud)

我想锁定管理员,这样一旦PersonData创建了一个对象,管理员用户就可以更改数据,但无法更改Person.

起初它看起来很简单 - 我把它放在PersonDataAdmin课堂上:

def get_readonly_fields(self, request, obj=None):
    if obj:
        return self.readonly_fields + ('person',)
    return self.readonly_fields
Run Code Online (Sandbox Code Playgroud)

在显示方面,这是按预期工作 - 我看到的值person,但它是灰色的所以我无法改变它 - 但是当我尝试更改数据并提交表单时,我收到一条错误消息, "请更正以下错误." 没有其他消息出现,但通过一些挖掘,我发现表单缺少必填person字段的值.

我已经研究了一个解决方案,它将涉及创建一个自定义表单,可以选择性地禁用这个字段(类似这个这个),但是(a)我没有成功地使它工作,并且(b)它似乎是一个对于看起来更简单的情况的大量代码.我也考虑过使用exclude,但遇到了同样的问题read_only.

有关如何实现这一目标的任何想法?谢谢!

小智 5

我通常做的是将模型中的字段设置为editable = false,然后在admin.py中将字段设置为只读,如下所示,

class PersonData(BaseModel):
    person = models.ForeignKey(Person, editable=False)
    data = models.TextField()
Run Code Online (Sandbox Code Playgroud)

然后在admin.py中

class PersonDataAdmin(admin.ModelAdmin):
    readonly_fields=('person',)
Run Code Online (Sandbox Code Playgroud)

希望这个有效!

  • 将模型字段设置为“editable=False”不会在管理员上显示并跳过验证。read_only 字段完成这项工作。参考:https://docs.djangoproject.com/en/3.1/ref/models/fields/#editable (3认同)

Tim*_*ley 5

我遇到了同样的问题。解决方法是在 Admin 类中定义一个方法,该方法返回要显示的只读字段的值。然后使用您之前使用字段名称的方法的名称。例如而不是:

class PersonDataAdmin(admin.ModelAdmin):
    readonly_fields=('person',)
Run Code Online (Sandbox Code Playgroud)

使用:

class PersonDataAdmin(admin.ModelAdmin):
    readonly_fields=('person_method',)

    def person_method(self, obj):
        return obj.person

    person_method.short_description = 'Person'
Run Code Online (Sandbox Code Playgroud)

Short_description 设置字段的标签。如果您不设置它,则该字段将被标记为“人员方法”

大概在 OP 情况下 get_readonly_fields 变为:

def get_readonly_fields(self, request, obj=None):
    if obj:
        return self.readonly_fields + ('person_method',)
    return self.readonly_fields
Run Code Online (Sandbox Code Playgroud)