Factory boy connect models to existing users

51 views Asked by At

Im populating my database with dummy data, I have separate Profile, User, Picture model. How can connect them to use same users?

class UserFactory(DjangoModelFactory):

    class Meta:
        model = User

    email = factory.Faker('email')
    first_name = factory.Faker('first_name')
    birthday = factory.Faker('date_object')
    age = factory.Faker('pyint', min_value=18, max_value=100)
    is_staff = False
    is_active = True

class UserPhotoFactory(DjangoModelFactory):

    class Meta:
        model = UserPhoto

    user = factory.RelatedFactory(UserFactory) #????
    order = factory.Faker('pyint', min_value=0, max_value=4)
    url = factory.Faker(
        'random_element', elements=[x for x in ['https://picsum.photos/seed/picsum/200/300', 'https://picsum.photos/seed/pssss/200/300', 'https://picsum.photos/seed/picwum/200/300']]
    )

class ProfileFactory(DjangoModelFactory):

    class Meta:
        model = Profile
    
    user = factory.SubFactory(UserFactory)
    bio = factory.LazyAttribute(lambda o: FAKE.paragraph(nb_sentences=5, ext_word_list=['abc', 'def', 'ghi', 'jkl']))

In this case I'm calling in shell

ProfileFacotry.create_batch(10)

And that creates users and their corresponding profiles. Now I want to add UserPhoto to the mix that is related to USER via ForeignKey like this

class UserPhoto(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    order = models.PositiveIntegerField(null=True)
    url = models.CharField(max_length=220)

What I want to achieve is to get 10 users 10 profiles and let say 20 pictures 2 for each user

1

There are 1 answers

0
SamSparx On BEST ANSWER

Rather than go via the subfactory of Profile, you can use FactoryBoy's reverse dependencies to create them for each user

This would look something like:

class UserFactory(DjangoModelFactory):

    class Meta:
        model = User

    email = factory.Faker('email')
    first_name = factory.Faker('first_name')
    birthday = factory.Faker('date_object')
    age = factory.Faker('pyint', min_value=18, max_value=100)
    is_staff = False
    is_active = True

    profile = factory.RelatedFactory(
        ProfileFactory,
        factory_related_name = 'profile',
        action=models.Profile.ACTION_CREATE,
    )

    image1 = factory.RelatedFactory(
        UserPhotoFactory,
        factory_related_name = 'user_photo',
        action=models.Profile.ACTION_CREATE,
    )

    image2 = factory.RelatedFactory(
        UserPhotoFactory,
        factory_related_name = 'user_photo',
        action=models.Profile.ACTION_CREATE,
    )