2016-09-17 59 views
1

Im 'オープンソースのdjango Webアプリケーションで作業していますが、いくつかのテスト用にモデルを設定するのにFactory Boyを使用したいと考えていますが、数時間後にドキュメントを読んで例を見ると、敗北を受け入れてここに尋ねる。DjangoのFactory Boyで従属モデルに値を渡す方法は?

class Customer(models.Model): 

    def save(self, *args, **kwargs): 
     if not self.full_name: 
      raise ValidationError('The full_name field is required') 
     super(Customer, self).save(*args, **kwargs) 


    user = models.OneToOneField(
     settings.AUTH_USER_MODEL, 
     on_delete=models.SET_NULL, 
     related_name='customer', 
     null=True 
    ) 

    created = models.DateTimeField() 
    created_in_billing_week = models.CharField(max_length=9) 
    full_name = models.CharField(max_length=255) 
    nickname = models.CharField(max_length=30) 
    mobile = models.CharField(max_length=30, default='', blank=True) 
    gocardless_current_mandate = models.OneToOneField(
     BillingGoCardlessMandate, 
     on_delete=models.SET_NULL, 
     related_name='in_use_for_customer', 
     null=True, 
    ) 

私もdjango.contrib.authから、標準Djangoのユーザーモデルを使用しています:

は、私は少しこのようになりますお客様のモデルを持っています。

はここに私の工場出荷時のコードです:私の場合は

class UserFactory(DjangoModelFactory): 

    class Meta: 
     model = get_user_model() 


class CustomerFactory(DjangoModelFactory): 

    class Meta: 
     model = models.Customer 

    full_name = fake.name() 
    nickname = factory.LazyAttribute(lambda obj: obj.full_name.split(' ')[0]) 

    created = factory.LazyFunction(timezone.now) 
    created_in_billing_week = factory.LazyAttribute(lambda obj: str(get_billing_week(obj.created))) 

    mobile = fake.phone_number() 

    user = factory.SubFactory(UserFactory, username=nickname, 
     email="{}@example.com".format(nickname)) 

、私はそう

CustomerFactory(fullname="Joe Bloggs") 

のような顧客を生成することができるようにしたい、正しいユーザ名と、生成された対応するユーザーを持っています、電子メールアドレス。

AttributeError: The parameter full_name is unknown. Evaluated attributes are {'email': '<factory.declarations.LazyAttribute object at 0x111d999e8>@example.com'}, definitions are {'email': '<factory.declarations.LazyAttribute object at 0x111d999e8>@example.com', 'username': <DeclarationWrapper for <factory.declarations.LazyAttribute object at 0x111d999e8>>}. 

私は、ユーザーの工場が作成される前に呼び出されていないお客様、ここで怠惰な属性に頼っていますので、これはあると思う:

は今のところ、私はこのエラーを取得しています。

どのように私はファクトリを使用して上記のように対応するユーザーでCustomerモデルインスタンスを作成することができますか?それはフルモデルは、その場合にはhere on the github repo

答えて

1

表示され、最良の方法はthe customer declarationsから値を選択することです価値がある何のため

class CustomerFactory(DjangoModelFactory): 

    class Meta: 
     model = models.Customer 

    full_name = factory.Faker('name') 
    nickname = factory.LazyAttribute(lambda obj: obj.full_name.split(' ')[0]) 

    created = factory.LazyFunction(timezone.now) 
    created_in_billing_week = factory.LazyAttribute(lambda obj: str(get_billing_week(obj.created))) 

    mobile = factory.Faker('phone_number') 

    user = factory.SubFactory(
     UserFactory, 
     username=factory.SelfAttribute('..nickname'), 
     email=factory.LazyAttribute(lambda u: "{}@example.com".format(u.username))) 
    ) 

また、各インスタンスのランダムな値を取得するためにfactory.Faker('field_name')を使用:クラス宣言のfullname = fake.name()の行は、

DEFAULT_FULL_NAME = fake.name() 

class CustomerFactory(DjangoModelFactory): 
    full_name = DEFAULT_FULL_NAME 

    class Meta: 
     model = models.customer 
と同等です。この工場で構築された各モデルに別の名前を提供します

class CustomerFactory(DjangoModelFactory): 
    full_name = factory.LazyFunction(fake.name) 

    class Meta: 
     model = models.customer 

すなわちfake.name()factory.Faker('name')一方

は同等です。

+0

甘い!本当にありがとうございました - それはまさに私が苦労していたものです! –

+0

簡潔にするために、ユーザSubfactory宣言の '' SelfAttribute'(http://factoryboy.readthedocs.io/en/latest/reference.html#parents)を使用して 'username = factory.SelfAttribute( '.. nickname')'直接の質問に対する解決策があるようだ。 ['SelfAttribute'を介してサブファクトリにフィールドをコピーするための工場の男の子のレシピ](http://factoryboy.readthedocs.io/en/latest/recipes.html?highlight=SelfAttribute#copying-fields-to-a-subfactory) –

関連する問題