DjangoModelFactory 具有 SubFactory 字段,该字段不会创建新条目,而是指向现有条目

gma*_*gno 4 python django factory-boy

假设我有:

class CompanyFactory(DjangoModelFactory):

    class Meta:
        model = Company

    name = factory.Faker("company")
    address = factory.Faker("address")


class InvoiceFactory(DjangoModelFactory):

    class Meta:
        model = Invoice

    company = factory.SubFactory(CompanyFactory)
    num = factory.Faker("numerify", text="#"*10)
    value_total = factory.Faker("random_number", digits=3)
Run Code Online (Sandbox Code Playgroud)

当我运行该InvoiceFactory.create()方法时,会创建一个新的发票条目。由于Invoice“链接”(外键)到Company,因此还会创建一个新的 Company 条目。


问题:

重写此方法的正确方法是什么,以便在调用InvoiceFactory.create()现有公司条目时选择而不是创建新条目?

小智 5

您有两个选择:

始终选择现有公司:

class InvoiceFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Invoice
    company = factory.Iterator(models.Company.objects.all())
Run Code Online (Sandbox Code Playgroud)

当创建第一张发票时,迭代器会被延迟计算。然而,它总是会在同一个工厂循环。

创建一些公司,然后重用:

首先,向django_get_or_create您的CompanyFactory: 如果提供的属性name已存在于数据库中,则将重用现有实例:

class CompanyFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Company
        django_get_or_create = ['name']
    name = factory.Faker('company')
    address = factory.Faker('address')
Run Code Online (Sandbox Code Playgroud)

name然后,从常量列表中为字段提供值(此处使用factory.fuzzy.FuzzyChoice):

class InvoiceFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Invoice
    company = factory.SubFactory(
        CompanyFactory,
        name=factory.fuzzy.FuzzyChoice(['PSF', 'Django', 'The Spanish Inquisition']),
    )
Run Code Online (Sandbox Code Playgroud)

一旦创建了前 3 个公司,它们将被重复用于所有后续对象。