Search code examples
djangofactories

django factory using a factory gives "Database access not allowed"


I want to create a user_profile from a factory called UserProfileFactory which uses a User object from UserFactory.

the error is: RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

here are the relivant classes.

from django.contrib.auth import get_user_model
from factory import Faker, post_generation
from factory.django import DjangoModelFactory

class UserFactory(DjangoModelFactory):

    username = Faker("user_name")
    email = Faker("email")
    name = Faker("name")

    @post_generation
    def password(self, create: bool, extracted: Sequence[Any], **kwargs):
        password = (
            extracted
            if extracted
            else Faker(
                "password",
                length=42,
                special_chars=True,
                digits=True,
                upper_case=True,
                lower_case=True,
            ).evaluate(None, None, extra={"locale": None})
        )
        self.set_password(password)

    class Meta:
        model = get_user_model()
        django_get_or_create = ["username"]



class UserProfileFactory(DjangoModelFactory):
    user = UserFactory.create()  #### the problem line ###
    country = Faker("country") # which laws apply
    birth_date = Faker("date_of_birth") # in the US you can't collect data from <13yo's

    class Meta:
        model = UserProfile

and in the tests/test.py

class TestUserProfileDetailView():
    def test_create_userprofile(self):
        """creates an APIRequest and uses an instance of UserProfile to test a view user_detail_view"""

        factory = APIRequestFactory()
        request = factory.get('/api/userprofile/')
        request.user = UserProfileFactory.create()  # problem starts here #
        response = user_detail_view(request)
        self.assertEqual(response.status_code, 200)

Solution

  • (I know this is an old one, but in case someone else finds this question later)

    I think what you want is the build method. The create method saves the instance in the database (which you said you don't want) but the build method doesn't.

    Here's an explanation in the factory-boy docs of build and create.