Django factory boy factory с отношениями OneToOne и связанной с ними областью

Я использую Factory Boy для создания тестовых фабрик для моего приложения django. Модель, с которой я столкнулся, - это очень простая модель учетной записи, которая имеет отношение OneToOne к модели пользователя django User (с использованием django < 1.5):

# models.py
from django.contrib.auth.models import User
from django.db import models

class Account(models.Model):
    user = models.OneToOneField(User)
    currency = models.CharField(max_length=3, default='USD')
    balance = models.CharField(max_length="5", default='0.00') 

Вот мои заводы:

# factories.py
from django.db.models.signals import post_save
from django.contrib.auth.models import User

import factory

from models import Account


class AccountFactory(factory.django.DjangoModelFactory):
    FACTORY_FOR = Account

    user = factory.SubFactory('app.factories.UserFactory')
    currency             = 'USD'
    balance              = '50.00'

class UserFactory(factory.django.DjangoModelFactory):
    FACTORY_FOR = User

    username = 'bob'
    account = factory.RelatedFactory(AccountFactory)

Итак, я ожидаю, что мальчик factory создаст связанный UserFactory всякий раз, когда вызывается AccountFactory:

# tests.py 
from django.test import TestCase

from factories import AccountFactory

class AccountTest(TestCase):

    def setUp(self):
        self.factory = AccountFactory()

    def test_factory_boy(self):
        print self.factory.id

Однако при запуске теста это похоже на создание нескольких моделей пользователей, и я вижу интегральную ошибку:

IntegrityError: column username is not unique

В документации упоминается наблюдение за циклами при работе с циркулярным импортом, но я не уверен, что это происходит, и как я его исправлю. docs

Если кто-нибудь, знакомый с factory Boy, может услышать или дать представление о том, что может вызвать эту ошибку целостности, было бы очень полезно!

Ответ 1

Я считаю, что это потому, что у вас есть круговая ссылка в ваших определениях factory. Попробуйте удалить строку account = factory.RelatedFactory(AccountFactory) из определения UserFactory. Если вы всегда будете ссылаться на создание учетной записи через AccountFactory, вам не нужна эта строка.

Кроме того, вы можете рассмотреть возможность присоединения последовательности к полю имени, так что если вам когда-нибудь понадобится больше одной учетной записи, она автоматически сгенерирует ее.

Измените: username = "bob" на username = factory.Sequence(lambda n : "bob {}".format(n)), и ваши пользователи будут называться "bob 1", "bob 2" и т.д.