【问题标题】:Cannot populate dummy data against ManyToManyField无法针对 ManyToManyField 填充虚拟数据
【发布时间】:2017-11-23 21:42:09
【问题描述】:

我正在尝试使用factoryboy 在我的项目中为 Django 模型创建测试数据。数据是通过Faker生成的,除了一个字段,即ManyToManyField;与来自django.contrib.auth.model 命名组的另一个内置模型的多对多关系。

class Voucher(models.Model):
    code = models.CharField(max_length=20, null=True, blank=True, unique=True)
    is_enabled = models.BooleanField('enable voucher', default=True, help_text='A soft delete mechanism for the voucher.')
    start_date = models.DateTimeField(null=True, blank=True)
    end_date = models.DateTimeField(null=True, blank=True)
    member_roles = models.ManyToManyField(to=Group, related_name='member_roles')

    def __str__(self):
        return "{}".format(self.code)

    class Meta:
        verbose_name = 'Voucher'
        verbose_name_plural = 'Vouchers'

这是我的模型,这是我为生成虚拟数据而创建的工厂:

class VoucherFactory(django.DjangoModelFactory):
    class Meta:
        model = 'app.Voucher'

    code = Faker('first_name')
    is_enabled = fuzzy.FuzzyChoice([True, False])
    start_date = fuzzy.FuzzyDateTime(datetime.datetime.now(pytz.utc))
    end_date = fuzzy.FuzzyDateTime(datetime.datetime.now(pytz.utc))

    @factory.post_generation
    def member_roles(self, create, extracted, **kwargs):
        if not create:
            return
        if extracted:
            for member_role in extracted:
                self.member_roles.add(member_role)

除了在Voucher 模型中针对这种多对多关系创建的voucher_member_roles 表之外,数据已成功填充。我也希望这个表也被填充。

我错过了什么?

【问题讨论】:

    标签: python django faker factory-boy


    【解决方案1】:

    制作凭证工厂时需要传入member_roles。例如:

    VoucherFactory.create(member_roles=[member_role1, member_role2])
    

    参见http://factoryboy.readthedocs.io/en/latest/recipes.html#simple-many-to-many-relationship 的声明:

    当调用 UserFactory() 或 UserFactory.build() 时,不会创建组绑定。 但是当调用 UserFactory.create(groups=(group1, group2, group3)) 时,groups 声明会将传入的组添加到用户的组集合中。

    【讨论】:

      【解决方案2】:

      如果要在工厂中生成依赖项,请使用:

      class VoucherFactory(django.DjangoModelFactory):
          class Meta:
              model = 'app.Voucher'
      
          code = Faker('first_name')
          is_enabled = fuzzy.FuzzyChoice([True, False])
          start_date = fuzzy.FuzzyDateTime(datetime.datetime.now(pytz.utc))
          end_date = fuzzy.FuzzyDateTime(datetime.datetime.now(pytz.utc))
      
          @factory.post_generation
          def member_roles(self, create, extracted, **kwargs):
              if not create:
                  return
              for _ in range(2):  # <- if you want more than one
                  self.member_roles.add(GroupFactory())
      

      【讨论】:

        猜你喜欢
        • 2019-02-10
        • 2017-10-08
        • 2011-02-23
        • 2023-01-15
        • 2021-01-09
        • 2020-05-18
        • 1970-01-01
        • 2019-05-04
        • 2019-05-25
        相关资源
        最近更新 更多