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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:40:16