如何在Django中实现保存Item时同步写入事务日志表?
实现Django模型保存时自动写入事务日志
当然可以实现,下面是两种适配你现有managed=False模型的靠谱方案:
方案一:重写Items模型的save方法
直接在Items的save方法中嵌入日志写入逻辑,这种方式直观且和模型绑定紧密:
修改你的Items模型代码如下:
from django.db import transaction from django.utils import timezone class Items(models.Model): itemid = models.CharField(primary_key=True, max_length=20) remarks = models.TextField(blank=True, null=True) resolution = models.TextField(blank=True, null=True) resolve = models.BooleanField(blank=True, null=True) resolve_date = models.DateField(blank=True, null=True) resolve_by = models.CharField(max_length=8, blank=True, null=True) recorded_by = models.CharField(max_length=8, blank=True, null=True) record_date = models.DateField(blank=True, null=True) class Meta: managed = False db_table = 'items' def save(self, *args, **kwargs): # 用事务确保数据一致性,两个操作要么都成功要么都回滚 with transaction.atomic(): is_new = self.pk is None # 判断是否为新增记录 super().save(*args, **kwargs) # 仅在新增时写入日志(和你原PostgreSQL函数逻辑对齐) if is_new: ItemsTransactionLog.objects.create( trans_desc='Add Clearance Item', trans_recorded=timezone.now().date() # 匹配表中DateField类型 )
方案二:使用Django的post_save信号
如果想把日志逻辑和模型解耦,方便后续扩展其他模型的日志需求,用信号是更合适的选择:
在你的models.py(或单独创建的signals.py模块)中添加以下代码:
from django.db.models.signals import post_save from django.dispatch import receiver from django.utils import timezone from django.db import transaction @receiver(post_save, sender=Items) def log_item_creation(sender, instance, created, **kwargs): # 仅在新增记录时触发日志写入 if created: with transaction.atomic(): ItemsTransactionLog.objects.create( trans_desc='Add Clearance Item', trans_recorded=timezone.now().date() )
如果使用单独的signals.py文件,需要在app的apps.py中注册信号:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app_name.signals
注意事项
- 因为你的模型设置了
managed=False,Django不会自动创建表结构,请确保数据库中已存在items和items_transactionlog两张表 - 原PostgreSQL函数中
now()返回带时间的类型,但你的ItemsTransactionLog.trans_recorded是DateField,所以用timezone.now().date()匹配类型;如果实际需要存储完整时间,记得把模型字段改成DateTimeField - 事务上下文管理器能保证两个写入操作的原子性,避免出现Items保存成功但日志写入失败的不一致情况
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

