如何在Django Admin中自动填充并设置created_by字段为只读
要解决created_by字段仍可编辑的问题,核心是把这个字段设置为只读,同时保证新建工单时自动填充当前登录管理员。给你两种实现方案:
方案一:创建时隐藏字段,编辑时只读显示
这种方式下,管理员新建工单时看不到created_by,系统自动填当前用户;编辑工单时这个字段会显示,但没法修改。
修改admin.py代码:
from django.contrib import admin from support.models import Ticket class TicketAdmin(admin.ModelAdmin): # 编辑页面要显示的字段列表,包含created_by fields = ['subject', 'body', 'priority', 'created_by'] readonly_fields = [] def get_readonly_fields(self, request, obj=None): # 编辑已有工单时,把created_by设为只读 if obj: return self.readonly_fields + ['created_by'] return self.readonly_fields def get_fields(self, request, obj=None): fields = super().get_fields(request, obj) # 新建工单时,移除created_by字段,不让管理员选 if not obj: fields.remove('created_by') return fields def save_model(self, request, obj, form, change): # 新建工单时自动填充当前登录的管理员 if not obj.created_by: obj.created_by = request.user super().save_model(request, obj, form, change) admin.site.register(Ticket, TicketAdmin)
方案二:创建时显示只读字段(自动填初始值)
如果想让管理员在创建工单时就能看到created_by字段(但不能改),用这个方案:
修改admin.py代码:
from django.contrib import admin from support.models import Ticket class TicketAdmin(admin.ModelAdmin): fields = ['subject', 'body', 'priority', 'created_by'] # 直接把created_by设为只读字段 readonly_fields = ['created_by'] def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) # 新建工单时,给created_by设置初始值为当前用户 if not obj: form.base_fields['created_by'].initial = request.user return form def save_model(self, request, obj, form, change): # 双重保险,确保字段一定会被填充为当前用户 if not obj.created_by: obj.created_by = request.user super().save_model(request, obj, form, change) admin.site.register(Ticket, TicketAdmin)
注意点
- 方案一更贴合“自动填充”的需求,减少管理员操作干扰;
- 两种方案都通过
save_model做了兜底,就算初始值没生效,也能保证字段被正确填充; - 要确认
request.user和Ticket模型里created_by关联的Users模型是兼容的(如果用了自定义用户模型,得确保Django认证系统用的是它)。
内容的提问来源于stack exchange,提问作者schneider99
相关产品推荐
相关产品推荐

