如何防止Django更新模型指定字段?以Action模型的by字段为例
解决Django Admin中Action模型by字段被覆盖的问题
方案一:在Admin里控制字段读写权限
给Action模型编写对应的Admin管理类,区分创建和编辑场景:创建新记录时自动填充当前登录用户,编辑时把by字段设为只读,禁止修改。
from django.contrib import admin from .models import Action @admin.register(Action) class ActionAdmin(admin.ModelAdmin): list_display = ('action', 'by', 'timestamp', 'note') def get_readonly_fields(self, request, obj=None): # 编辑已有记录时,将by字段加入只读列表 if obj: return self.readonly_fields + ('by',) return self.readonly_fields def save_model(self, request, obj, form, change): # 新建记录时,自动把当前登录用户设为by字段的值 if not change: obj.by = request.user super().save_model(request, obj, form, change)
方案二:模型层面直接锁定字段(可选)
如果想彻底禁止任何场景下修改已创建记录的by字段,可以给模型中的by字段添加editable=False属性,但需要确保创建时通过代码自动赋值用户:
修改Action模型代码:
class Action(models.Model): action = models.ForeignKey(TaskAction, models.CASCADE) # 添加editable=False,让字段默认不在表单中显示 by = models.ForeignKey('auth.User', models.CASCADE, editable=False) timestamp = models.DateTimeField(auto_now_add=True, editable=False) note = models.TextField(blank=True, null=True) def __str__(self): return str(self.action) class Meta: verbose_name = 'Task Action' verbose_name_plural = 'Task Actions' db_table = 'task_actions'
同时仍需在Admin的save_model方法中加入自动赋值用户的代码,和方案一中的save_model部分一致。
关键说明
- 方案一更灵活,创建时可手动选择用户(如有需求),编辑时锁定字段;方案二直接将字段锁死,只能通过代码赋值。
- 核心逻辑是区分新建记录和编辑已有记录:新建时设置用户,编辑时禁止修改
by字段。
内容的提问来源于stack exchange,提问作者Kirubel
相关产品推荐
相关产品推荐

