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
相关产品推荐
相关产品推荐

