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

Django抽象模型自引用字段的Factory Boy递归错误求助

解决递归错误的方案

问题原因

你的BaseOrganizationFactory中,parent字段默认配置了factory.SubFactory("myapp.tests.factories.BaseOrganizationFactory")。这意味着每次创建实例时,Factory会自动递归创建一个父级实例,而该父级实例又会触发自身的父级创建,形成无限循环,最终超出Python的递归深度限制。

解决方法

方法一:设置parent默认值为None(最直接的方案)

修改BaseOrganizationFactory的定义,将parent的默认值设为None,与模型字段的空值配置匹配,默认创建时不再自动生成父级:

class BaseOrganizationFactory(factory.django.DjangoModelFactory):
    """Base organization factory"""
    name = factory.Faker("company")
    juridical_address = factory.Faker("address")
    phone_number = factory.Faker("phone_number")
    
    # 直接设置parent默认值为None,避免递归
    parent = None

如果需要创建带有父级的组织实例,只需在调用Factory时显式指定父级:

parent_org = BaseOrganizationFactory()
child_org = BaseOrganizationFactory(parent=parent_org)

方法二:条件式创建父级(适用于动态控制场景)

如果需要保留“可选创建父级”的能力,可以用factory.Maybe实现,仅在指定条件下生成父级:

class BaseOrganizationFactory(factory.django.DjangoModelFactory):
    """Base organization factory"""
    name = factory.Faker("company")
    juridical_address = factory.Faker("address")
    phone_number = factory.Faker("phone_number")
    
    # 默认不创建父级
    has_parent = factory.Faker("boolean", chance_of_getting_true=0)
    
    parent = factory.Maybe(
        "has_parent",
        yes_declaration=factory.SubFactory("myapp.tests.factories.BaseOrganizationFactory"),
        no_declaration=None,
    )

默认情况下不会生成父级,若需要带父级的实例,只需传入has_parent=True即可。

额外注意事项

由于BaseOrganization是抽象模型(Meta.abstract = True),Django不允许直接创建抽象模型的实例。你应该将BaseOrganizationFactory作为基类,供具体组织模型的Factory继承使用,例如:

# 定义具体的组织模型
class Company(BaseOrganization):
    # 新增具体模型专属字段
    pass

# 定义对应Factory
class CompanyFactory(BaseOrganizationFactory):
    class Meta:
        model = Company

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:57