10

我目前factory_boy用于在我的测试中创建固定装置。 Factory_boy文档只提到了哪些可以像模型中的字段SubFactory一样起作用。ForeignKey但是,ManyToMany 关联上没有任何内容。如果我有一个以下 Post 模型,我将如何为它创建一个工厂?

class Post(models.Model):
    title = models.CharField(max_length=100)
    tags = models.ManyToManyField('tags.Tag')

class PostFactory(factory.Factory):
    FACTORY_FOR = Post

    title = 'My title'
    tags = ???
4

3 回答 3

11

post_generation 钩子怎么样- 我假设您使用较新版本的factory_boy

import random
import factory

class PostFactory(factory.Factory):
    FACTORY_FOR = Post
    title = factory.Sequence(lambda n: "This is test title number" + n)
    @factory.post_generation(extract_prefix='tags')
    def add_tags(self, create, extracted, **kwargs):
        # allow something like PostFactory(tags = Tag.objects.filter())
        if extracted and type(extracted) == type(Tag.objects.all()):
            self.tags = extracted
            self.save()
        else:
            if Tag.objects.all().count() < 5:
                TagFactory.create_batch(5, **kwargs)
            for tag in Tag.objects.all().order_by('?')[:random.randint(1, 5)]:
                self.tags.add(tag)

请注意,您可以使用PostFactory(tags__field = 'some fancy default text'),但我建议使用 Sequences 创建好的TagFactory...

您应该可以绑定PostFactory(tags = Tag.objects.filter()),但这部分未经测试...

于 2012-09-11T08:05:23.953 回答
7

您可以覆盖_prepare类方法:

class PostFactory(Factory):
    FACTORY_FOR = Post

    title = 'My title'

    @classmethod
    def _prepare(cls, create, **kwargs):
        post = super(PostFactory, cls)._prepare(create, **kwargs)
        if post.id:
            post.tags = Tag.objects.all()
        return post

请注意,如果帖子没有 ID,您将无法向帖子添加标签。

于 2012-07-19T05:29:27.087 回答
2

我没有测试它,但有什么问题:

class PostFactory(factory.Factory):
    FACTORY_FOR = Post
    title = 'My title'

class TagFactory(factory.Factory):
    FACTORY_FOR = Tag

post = PostFactory()
tag = TagFactory()
post.tags.add(tag)
于 2012-05-19T01:28:33.810 回答