factory_boy icon indicating copy to clipboard operation
factory_boy copied to clipboard

Many To Many field fixture special function

Open RedMoon32 opened this issue 5 years ago • 2 comments

The problem

Its a bit annoying to write list init for many to many fields in the following way:

(Example)

class UserFactory(factory.DjangoModelFactory):
    class Meta:
        model = User

    email = factory.Faker("email")

    @factory.post_generation
    def tickets(self, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            for access in extracted:
                self.tickets.add(access)

    @factory.post_generation
    def accesses(self, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            for access in extracted:
                self.accesses.add(access)

to be used with user = UserFactory(tickets=[TicketFactory()], accesses= [AccessFactory(),...]

Proposed solution

I propose to create special wrapper which will work in the following way:

class UserFactory(factory.DjangoModelFactory):
    class Meta:
        model = User

    email = factory.Faker("email")
    tickets = factory.django.ManyToManyFromList() # function like above will be returned
    accesses = factory.django.ManyToManyFromList()

Extra notes

Btw, I can create a PR

RedMoon32 avatar Jul 14 '20 09:07 RedMoon32

What is the interest of adding the list of related object as a kwarg to the user factory versus the following?

>>> user = UserFactory.create()
>>> user.tickets.add([TicketFactory()]])

francoisfreitag avatar Nov 07 '20 12:11 francoisfreitag

we will be able to handle the creation of the object and creation of the nested many to many fields in one line, so if we create many such objects manually we will have less overloaded code (one line for each object creation instead of two)

RedMoon32 avatar Nov 09 '20 08:11 RedMoon32