无法针对ManyToManyField填充虚拟数据

时间:2017-06-21 06:33:25

标签: python django faker factory-boy

我正在尝试使用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_member_roles模型中针对此多对多关系创建的Voucher表外,数据已成功填充。我希望这个表也可以填充。

我缺少什么?

2 个答案:

答案 0 :(得分: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声明将添加成组传递给用户的组。

答案 1 :(得分:0)

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

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())