Search code examples
pythondjangopython-3.xfactory-boy

Django Factory boy usage


Given the following models:

from django.db import models


class A(models.Model):
    foo = models.TextField()


# B inherits from A, it's not abstract so it should 
# create a table with a foreign key relationship
class B(A):
    bar = models.TextField()

And the following test with DjangoModel factories:

from django.test import TestCase
import factory
from factory.django import DjangoModelFactory
from .models import A, B


class AFactory(DjangoModelFactory):
    foo = factory.Faker('name')

    class Meta:
        model = A


class BFactory(DjangoModelFactory):
    bar = factory.Faker('name')

    class Meta:
        model = B


class BTestCase(TestCase):
    def test_1(self):
        b = BFactory()
        print(b.foo)  # prints ''

How can I get b.foo to refer to an actual A entity with a valid foo attribute?

At the moment b.foo just returns an empty string. But if I create an A entity using the AFactory, the entity has a properly populated foo field:

>>> a_ent = AFactory()
>>> a_ent.foo
'Nicholas Williams'

I would like BFactory to create an A entity for me that b can refer to.

Is that possible?


Solution

  • You only need to extend BFactory from AFactory:

    class AFactory(DjangoModelFactory):
        foo = factory.Faker('name')
    
        class Meta:
            model = A
    
    
    class BFactory(AFactory):
        bar = factory.Faker('name')
    
        class Meta:
            model = B
    
    b = BFactory()
    print(b.foo)  # Robert Rogers
    print(b.bar)  # Maria Clark
    

    BFactory is used to create the database records through the B model, so for this to work you need to define the factory fields on the BFactory. This can be easily done with the inheritance above.