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

使用Factory Boy构建Django关联模型时报递归深度超限错误如何解决

报错原因

你遇到的递归错误是双向自动创建关联对象形成了无限循环导致的,循环链路如下:

  1. 调用UserFactory()创建用户时,你定义的RelatedFactory会自动创建绑定当前用户的Employee实例
  2. 创建Employee实例时,user和creator两个字段都声明了SubFactory(UserFactory),会再次触发新的User实例创建
  3. 新创建的User又会触发RelatedFactory创建新的Employee,无限重复直到栈溢出。
推荐解决方案

取消双向自动绑定逻辑,改为主动控制关联对象的创建,同时复用关联字段避免重复生成用户:

  1. 移除UserFactory中自动创建Employee的RelatedFactory,改用post_generation参数按需生成关联的Employee
  2. EmployeeFactory的creator字段默认复用自身绑定的user,避免额外创建新用户

修改后的代码如下:

class UserFactory(factory.django.DjangoModelFactory):
  class Meta:
      model = User

  first_name = fake.first_name()
  last_name = fake.last_name()
  username = factory.Sequence(lambda n: "user_%d" % n)
  email = fake.ascii_email()

  # 可选参数,主动传入True时才会生成关联的Employee
  @factory.post_generation
  def with_employee(self, create, extracted, **kwargs):
      if not create or not extracted:
          return
      EmployeeFactory(user=self, creator=self, **kwargs)


class EmployeeFactory(factory.django.DjangoModelFactory):
  class Meta:
      model = Employee

  first_name = fake.first_name()
  last_name = fake.last_name()
  phone = "+88005553535"
  email = fake.ascii_email()
  user = factory.SubFactory(UserFactory)
  # 复用当前Employee关联的user作为creator,避免额外创建新User
  creator = factory.SelfAttribute('user')

使用方式:

  • 仅创建无关联Employee的用户:user = UserFactory()
  • 创建用户同时生成关联的Employee:user = UserFactory(with_employee=True)
  • 单独创建Employee:employee = EmployeeFactory(),自动生成关联用户,creator默认和关联用户一致
  • 自定义creator:other_user = UserFactory(); employee = EmployeeFactory(creator=other_user)
备选方案(保留User自动创建Employee的逻辑)

如果需要保留UserFactory默认自动生成关联Employee的逻辑,可以通过参数控制打断循环:

class UserFactory(factory.django.DjangoModelFactory):
  class Meta:
      model = User
      exclude = ('create_employee',)
  
  # 控制是否自动创建关联Employee,不写入数据库
  create_employee = True
  first_name = fake.first_name()
  last_name = fake.last_name()
  username = factory.Sequence(lambda n: "user_%d" % n)
  email = fake.ascii_email()

  employee = factory.RelatedFactory(
      "control_room.tests.factories.EmployeeFactory",
      factory_related_name='user'
  )


class EmployeeFactory(factory.django.DjangoModelFactory):
  class Meta:
      model = Employee

  first_name = fake.first_name()
  last_name = fake.last_name()
  phone = "+88005553535"
  email = fake.ascii_email()
  # 创建关联user时关闭自动生成Employee的逻辑,打断循环
  user = factory.SubFactory(UserFactory, create_employee=False)
  creator = factory.SubFactory(UserFactory)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:36:06