簡體   English   中英

如何使用 Django 中的 Factory Boy 將值傳遞給依賴模型?

[英]How to I pass values into dependent models with Factory Boy in Django?

我正在開發一個開源 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 模型實例,以及如上所述的相應用戶,我應該怎么做?

對於完整模型的價值,可以在 github repo 上看到這里

在這種情況下,最好的方法是從客戶聲明中選擇值:

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

factory.Faker('name')相當於:

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

    class Meta:
        model = models.customer

fake.name()將為使用此工廠構建的每個模型提供不同的名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM