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

使用django-pgtrigger遇Meta类triggers未定义错误,求日志实现方案

问题1:NameError: name 'triggers' is not defined

这个错误是因为Django的Model.Meta类默认不识别triggers属性,改用@pgtrigger.register装饰器是更稳妥的触发器注册方式,修改后的代码如下:

from django.db import models
import pgtrigger

@pgtrigger.register(
    pgtrigger.Protect(
        name='protect_deletes',
        operation=pgtrigger.Delete,
        condition=pgtrigger.Q(old__is_active=True)
    )
)
class ProtectedModel(models.Model):
    """Active object cannot be deleted!"""
    is_active = models.BooleanField(default=True)

如果坚持使用Meta类的方式,需要确保:

  • pgtrigger已添加到项目的INSTALLED_APPS配置中
  • 执行过python manage.py makemigrations和python manage.py migrate命令,将触发器同步到数据库
  • 代码缩进正确,triggers确实定义在Meta类内部

问题2:基于触发器的数据库日志方案

方案1:使用django-pghistory(与django-pgtrigger配套)

这是官方推荐的日志工具,能自动通过触发器记录模型的所有变更,上手非常简单:

  1. 安装依赖:pip install django-pghistory
  2. 在INSTALLED_APPS中添加pghistory
  3. 用@pghistory.track()装饰需要记录日志的模型:
import pghistory
from django.db import models

@pghistory.track()
class YourModel(models.Model):
    name = models.CharField(max_length=100)
    # 其他业务字段...

执行migrations后,会自动生成对应的历史表,所有增删改操作都会被记录,包括变更前后的数据、操作时间、执行用户等信息。

方案2:自定义触发器日志

如果需要更灵活的日志内容控制,可以用django-pgtrigger手动实现:

  1. 先创建日志模型:
from django.db import models
from django.utils import timezone

class ModelChangeLog(models.Model):
    model_name = models.CharField(max_length=100)
    object_id = models.CharField(max_length=255)
    change_type = models.CharField(max_length=10, choices=[('INSERT', '新增'), ('UPDATE', '更新'), ('DELETE', '删除')])
    old_data = models.JSONField(null=True)
    new_data = models.JSONField(null=True)
    changed_at = models.DateTimeField(default=timezone.now)
    changed_by = models.CharField(max_length=100, null=True)  # 可结合request记录操作用户
  1. 用pgtrigger.Trigger定义触发器逻辑,通过SQL函数插入日志:
import pgtrigger

@pgtrigger.register(
    pgtrigger.Trigger(
        name='log_yourmodel_changes',
        operation=pgtrigger.Insert | pgtrigger.Update | pgtrigger.Delete,
        func=pgtrigger.Func(
            """
            INSERT INTO yourapp_modelchangelog (
                model_name, object_id, change_type, old_data, new_data, changed_at
            ) VALUES (
                'YourModel',
                CASE WHEN TG_OP = 'DELETE' THEN OLD.id ELSE NEW.id END,
                TG_OP,
                CASE WHEN TG_OP != 'INSERT' THEN row_to_json(OLD) ELSE NULL END,
                CASE WHEN TG_OP != 'DELETE' THEN row_to_json(NEW) ELSE NULL END,
                NOW()
            );
            """
        ),
        when=pgtrigger.After
    )
)
class YourModel(models.Model):
    name = models.CharField(max_length=100)
    # 其他业务字段...

这种方式可以完全自定义日志内容,但需要编写SQL函数,适合有特定需求的场景。


内容的提问来源于stack exchange,提问作者Nick S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:45:32