Django TabularInline设置字符串类型只读主键保存对象报错如何解决?
问题原因
这是Django 3.2版本中,针对非自增类型自定义主键的模型在内联Admin中设置主键为只读字段时的已知异常:
当你把原生主键id直接加入readonly_fields时,Django Admin的内联表单不会将该只读字段的值随表单提交,后端校验时无法获取到现有Child实例的主键值,会误将现有实例判断为需要新建的实例,而主键作为必填字段缺失就触发了表单报错。
解决方案
不要直接把原生id字段加入只读字段列表,而是自定义一个展示字段来显示主键值:
class ChildMemberLinkAdmin(admin.TabularInline): model = Child extra = 0 # 这里用自定义的display_id替代原生id字段 fields = ("display_id", "name") readonly_fields = ("display_id",) def display_id(self, obj): # 返回实例的主键值用于展示 return obj.id # 给自定义字段设置显示名称 display_id.short_description = "ID" @admin.register(Parent) class ParentAdmin(admin.ModelAdmin): fields = ("name",) inlines = (ChildMemberLinkAdmin,)
这种方案不会影响原有逻辑,既能正常展示主键值,也不会触发表单校验错误。
如果有升级Django版本的条件,也可以升级到Django 4.0及以上版本,该版本已经修复了这个异常,原有的配置代码可以直接正常运行。
内容的提问来源于stack exchange,提问作者seladb
相关产品推荐
相关产品推荐

