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

Django重写模型save()方法后数据迁移时table_fields为空如何解决

问题原因
  • 迁移操作中通过apps.get_model()获取的是迁移快照里的历史版本模型,不会加载你在models.py中自定义的save()方法、类常量等业务逻辑
  • 你使用的bulk_create批量插入方法本身不会触发单个模型实例的save()方法,所以写在save中的默认值赋值逻辑完全没有执行
修复方案

方案1:修改迁移文件的数据生成逻辑

直接在迁移的make_report_fields函数中手动定义字段映射、给每个实例赋值table_fields,不需要依赖模型层的逻辑,修改后的迁移函数代码如下:

def make_report_fields(apps, schema_editor):
    User = apps.get_model(settings.AUTH_USER_MODEL)
    Report = apps.get_model('deal', 'Report')
    # 直接在迁移逻辑里定义字段映射
    DEFAULT_TABLE_FIELDS = {
        'OrderTrendReport': ('card', 'board', 'customer', 'amount',
                             'currency', 'stage', 'owner', 'country',
                             'local_ordered_date', 'local_delivery_deadline',
                             'order_number'),
        'RevenueTrendReport': ('card', 'customer', 'invoice_total',
                               'payment_total', 'balance', 'currency',
                               'owner', 'order_number', 'board'),
        'DealSuccessRateReport': ('card', 'board', 'customer', 'amount',
                                  'currency', 'owner', 'result',
                                  'local_result_updated_at'),
        'DealLostReasonReport': ('card', 'board', 'customer', 'amount',
                                 'currency', 'owner',
                                 'local_result_updated_at', 'lost_reason',
                                 'lost_description'),
        'OrderByCategoryReport': ('card', 'board', 'customer', 'amount',
                                  'currency', 'stage', 'owner', 'country',
                                  'local_ordered_date', 'local_delivery_deadline',
                                  'order_number')
    }
    ReportTypes = DEFAULT_TABLE_FIELDS.keys()
    report_fields = [
        Report(
            user=user, 
            report_type=report_type,
            # 直接赋值对应字段列表,转为list适配ArrayField格式
            table_fields=list(DEFAULT_TABLE_FIELDS[report_type])
        )
        for report_type in ReportTypes
        for user in User.objects.all()
    ]
    Report.objects.bulk_create(report_fields)

如果已经执行过该迁移,先运行python manage.py migrate deal 0059回滚到上一个版本,修改迁移文件后再重新执行迁移即可。

方案2:(可选)优化模型层逻辑

你现有写在save中的逻辑在普通单实例保存场景下可以正常生效,但如果后续用到bulk_create、QuerySet.update等批量操作时还是不会触发save逻辑,需要在这类操作时手动给table_fields赋值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 14:24:05