我的模型文件中有一个不可编辑字段的模型。
class Table(models.Model):
label = models.CharField(max_length=40, editable=False)
在我的管理网站中,更新现有表对象时,我无法编辑标签。没关系,这正是我想要的这个约束。但是,当尝试使用管理站点创建对象时,该字段仍然处于隐藏状态,因此我只能使用 shell 创建 Table 对象。
如何使此字段仅在创建时显示,但在更新时显示为只读?谢谢。
方法 1
使标签字段在创建时显示,但在更新时将其完全删除。我们将使用 ModelAdmin.get_exclude 和 ModelAdmin.get_fields 钩子来实现此目的。
## models.py
class Table(models.Model):
label = models.CharField(max_length=40) # remove editable option
## admin.py
@admin.register(Table)
class TableAdmin(admin.ModelAdmin):
non_editable_fields = ['label']
def get_exclude(self, request, obj=None):
defaults = super().get_exclude(request, obj=obj) or ()
if obj: # if we are updating an object
defaults = (*defaults, *self.non_editable_fields)
return defaults or None
def get_fields(self, request, obj=None):
defaults = super().get_fields(request, obj=obj)
if obj: # if we are updating an object
defaults = tuple(f for f in defaults if f not in self.non_editable_fields)
return defaults
方法2
使标签字段在创建和更新时都显示,但在更新时使其只读。 Django 管理员为此功能提供了一个钩子,它被称为ModelAdmin.get_readonly_fields
。您可以在此处找到文档。
因此,我们可以编写以下代码来创建字段,该字段可以在创建对象时显示/添加,但尽管显示设置值(通过管理站点(,但无法进一步编辑。
## models.py
class Table(models.Model):
label = models.CharField(max_length=40) # remove editable option
## admin.py
@admin.register(Table)
class TableAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
defaults = super().get_readonly_fields(request, obj=obj)
if obj: # if we are updating an object
defaults = tuple(defaults) + ('label', ) # make sure defaults is a tuple
return defaults
方法2的奖励
此外,如果该表上有多个字段,则可以使用 fields 属性来设置排序(未专门排序的只读字段将显示在字段列表的末尾(。这种排序方法的缺点是,每次在模型中进行更改时,都必须记住将模型更改反映到fields
属性。
尝试在文件中使用readonly_fields
admin.py
class TableAdmin(admin.ModelAdmin):
readonly_fields = ('label',)
admin.site.register(Table, TableAdmin)