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

如何在数据库层面强制Django模型自动生成时间戳

解决方案

方案1:使用__init_subclass__自动为所有子类注册触发器

直接在抽象模型的__init_subclass__方法中,给每个继承的非抽象子类自动注册触发器,无需逐个手动添加:

import pgtrigger
from django.db import models


class AbstractAppendOnly(models.Model):
    created_at = models.DateTimeField(auto_now=True, editable=False)
    db_note = models.TextField(default=None, null=True)

    class Meta:
        abstract = True

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        # 仅为实际生成数据库表的非抽象模型注册触发器
        if not cls._meta.abstract:
            pgtrigger.register(
                pgtrigger.Trigger(
                    name='insert_auto_created_at_timestamp',
                    operation=pgtrigger.Insert,
                    when=pgtrigger.Before,
                    func='''
                        new.created_at = now();
                        return new;
                    '''
                )
            )(cls)

该方案无额外侵入性,所有继承AbstractAppendOnly的业务模型会自动获得数据库层的时间戳强制逻辑,不会再出现抽象类无对应数据表的报错。

方案2:直接配置字段数据库级默认值(Django 3.2+支持)

Django 3.2及以上版本已原生支持db_default参数,可以直接在字段定义时设置数据库层面的默认值,无需触发器也无需自定义迁移,实现更轻量:

from django.db import models


class AbstractAppendOnly(models.Model):
    # db_default会自动在表结构中添加DEFAULT约束
    created_at = models.DateTimeField(auto_now=True, editable=False, db_default=models.functions.Now())
    db_note = models.TextField(default=None, null=True)

    class Meta:
        abstract = True

生成迁移时会自动在CREATE TABLE语句中给created_at字段添加DEFAULT CURRENT_TIMESTAMP约束,完美满足数据库层面强制时间戳的要求。如果使用的Django版本低于3.2,建议升级后使用该方案,复杂度远低于触发器方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 03:24:03