Python factory_boy library m2m in Django model?

让人想犯罪 __ 提交于 2019-12-03 07:34:40

问题


I'm currently using factory_boy for creating fixtures in my tests. Factory_boy docs only mentioned about SubFactory which could act like a ForeignKey field in a model. However, there was nothing on ManyToMany association. If I had a following Post model, how would I go about creating a factory for it?

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 = ???

回答1:


What about post_generation hook - I assume You use newer version of 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)

Note that You can use PostFactory(tags__field = 'some fancy default text'), but I recommend to create good TagFactory with Sequences ...

You should be able to bind PostFactory(tags = Tag.objects.filter()) but this part is not tested ...




回答2:


You can override the _prepare classmethod:

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

Note that you can't add tags to a post if the post doesn't have an ID.




回答3:


I did not test it, but what is the problem with:

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)


来源:https://stackoverflow.com/questions/10283544/python-factory-boy-library-m2m-in-django-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!