如何为Django模型添加created_by和modified_by字段?
实现步骤
1. 为LockData模型添加字段
首先在sample/models.py中导入django.conf.settings,然后在LockData类中添加两个关联自定义用户模型的外键字段:
from django.conf import settings from django.db import models # 保留原有的其他导入... class LockData(models.Model): patient=models.ForeignKey(Patient, on_delete=CASCADE, default=None) patient_type=models.ForeignKey(PatientType, on_delete=CASCADE, default=None, blank=True, null=True) lock=models.BooleanField(default=False) date=models.DateField(default=datetime.date.today) created_on=models.DateTimeField(auto_now_add=True) modified_on=models.DateTimeField(auto_now=True) # 新增created_by和modified_by字段 created_by = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='lockdata_created' ) modified_by = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='lockdata_modified' )
- 使用
settings.AUTH_USER_MODEL是Django推荐的关联自定义用户模型的方式,避免硬编码依赖。 on_delete=models.SET_NULL表示当关联用户被删除时,字段值设为null,你可根据业务需求改为PROTECT(禁止删除关联用户)等其他选项。related_name用于反向查询,方便从用户实例快速查找其创建/修改的LockData记录。
2. 自动填充字段值
有两种实用方式实现自动赋值,任选其一即可:
方式一:重写模型save方法(需在视图传递用户)
如果视图中能直接获取当前登录用户,可重写save方法接收用户参数,自动赋值:
class LockData(models.Model): # 保留原字段定义... def save(self, *args, user=None, **kwargs): if user and not self.pk: # 新建记录时设置created_by self.created_by = user if user: # 每次保存都更新modified_by self.modified_by = user super().save(*args, **kwargs)
在视图中保存实例时,传入当前用户:
# 示例:在类视图的post方法中 def post(self, request): form = LockDataForm(request.POST) if form.is_valid(): lock_data = form.save(commit=False) lock_data.save(user=request.user) # 其他业务逻辑...
方式二:使用Django信号+线程本地存储(全自动)
这种方式无需在视图中手动传递用户,通过中间件存储当前用户,再用信号自动赋值:
步骤2.1:创建中间件存储当前用户
在项目根目录下新建middleware.py,添加以下代码:
import threading from django.utils.deprecation import MiddlewareMixin _thread_locals = threading.local() def get_current_user(): return getattr(_thread_locals, 'user', None) class CurrentUserMiddleware(MiddlewareMixin): def process_request(self, request): _thread_locals.user = request.user if request.user.is_authenticated else None
然后在settings.py的MIDDLEWARE列表中注册该中间件:
MIDDLEWARE = [ # 保留原有中间件... '你的项目名称.middleware.CurrentUserMiddleware', ]
步骤2.2:编写信号处理函数
在sample/models.py末尾添加信号逻辑:
from django.db.models.signals import pre_save from django.dispatch import receiver from .middleware import get_current_user @receiver(pre_save, sender=LockData) def set_user_fields(sender, instance, **kwargs): user = get_current_user() if user: if not instance.pk: # 新建记录时赋值created_by instance.created_by = user instance.modified_by = user # 每次保存都更新modified_by
这样无论在何处保存LockData实例,只要当前有登录用户,字段都会自动赋值。
3. 执行数据库迁移
添加字段后,运行以下命令完成数据库更新:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者noob87
相关产品推荐
相关产品推荐

