在 Django 后台中创建对象时如何使不可编辑字段出现?



我的模型文件中有一个不可编辑字段的模型。

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_fieldsadmin.py

class TableAdmin(admin.ModelAdmin):
readonly_fields = ('label',)
admin.site.register(Table, TableAdmin)

最新更新