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

django_get_or_create无法创建实例:数组字段未填充问题求助

问题与解决方案

问题描述

我通过SubFactory使用ModelFactory,原本Meta类的django_get_or_create参数仅包含('code')。为模型新增两个数组字段后将它们加入该参数,现在出现两个问题:

  • 无法创建code为'RU'的实例,测试中多次输出Turkey(TR的别名)
  • 新增的数组字段未填充,输出空数组[]

相关代码:

class ModelFactory(DjangoModelFactory):
    code = "RU"
    predefined_amounts_one_time = [500, 1000, 3000]
    predefined_amounts_recurring = [500, 1000, 3000]

    class Meta:
        model = Model
        django_get_or_create = ("predefined_amounts_one_time", "predefined_amounts_recurring", "code")

问题原因

  1. 数组字段无法作为django_get_or_create的查询条件:Django ORM对数组类型字段(比如PostgreSQL的ArrayField)的比对支持有限,get_or_create尝试用数组字段查询时,无法匹配到预设的[500,1000,3000],导致查询失败。
  2. 查询失败后的逻辑冲突:查询不到匹配记录时,Factory可能触发了其他关联逻辑(比如SubFactory中已存在TR的实例),返回了Turkey的记录而非新创建的RU实例。
  3. 数组字段未填充:由于查询失败后创建新实例的流程异常,预设的数组字段默认值没有被正确传入模型。

解决方案

方案1:移除django_get_or_create中的数组字段

数组字段不适合作为唯一查询标识,保留code作为唯一键即可:

class ModelFactory(DjangoModelFactory):
    code = "RU"
    predefined_amounts_one_time = [500, 1000, 3000]
    predefined_amounts_recurring = [500, 1000, 3000]

    class Meta:
        model = Model
        django_get_or_create = ("code",)

方案2:手动处理get_or_create逻辑(需确保数组字段唯一性时用)

如果必须保证code和数组字段的组合唯一,重写Factory的_create方法,手动实现查询、创建或更新逻辑:

class ModelFactory(DjangoModelFactory):
    code = "RU"
    predefined_amounts_one_time = [500, 1000, 3000]
    predefined_amounts_recurring = [500, 1000, 3000]

    class Meta:
        model = Model

    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        # 仅用code查询,数组字段作为默认值传入
        obj, created = model_class.objects.get_or_create(
            code=kwargs["code"],
            defaults={
                "predefined_amounts_one_time": kwargs["predefined_amounts_one_time"],
                "predefined_amounts_recurring": kwargs["predefined_amounts_recurring"],
            }
        )
        # 若实例已存在,检查数组字段是否匹配,不匹配则更新
        if not created:
            need_update = False
            if obj.predefined_amounts_one_time != kwargs["predefined_amounts_one_time"]:
                obj.predefined_amounts_one_time = kwargs["predefined_amounts_one_time"]
                need_update = True
            if obj.predefined_amounts_recurring != kwargs["predefined_amounts_recurring"]:
                obj.predefined_amounts_recurring = kwargs["predefined_amounts_recurring"]
                need_update = True
            if need_update:
                obj.save()
        return obj

方案3:检查SubFactory关联逻辑

排查SubFactory的代码,确认是否有逻辑覆盖了RU实例的创建,导致错误返回TR的Turkey记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:34:49