Python factory_boy library m2m in Django model?

django, factory, fixtures, python, testing

Solution

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 ...

Problem

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

Original source