You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:15:37