如何使用共享某些属性的外键实例创建工厂,但是该属性在父对象上不存在?

时间:2019-07-15 23:43:39

标签: python django factory-boy

我希望使用FactoryBoy来确保使用相同实例生成具有与其他模型间接共享外键的外键的模型(我知道这很难理解,这是一个代码示例):

from django.db import models
import factory


class Foo(models.Model):
    name = models.CharField(max_length=32)

class Bar(models.Model):
    foo = models.ForeignKey(Foo, on_delete=models.PROTECT)

class Baz(models.Model):
    foo = models.ForeignKey(Foo, on_delete=models.PROTECT)

class HasBarAndBaz(models.Model):
    bar = models.ForeignKey(Bar, on_delete=models.PROTECT)
    baz = models.ForeignKey(Baz, on_delete=models.PROTECT)

class HasBarAndBazFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = HasBarAndBaz

    bar = factory.SubFactory(BarFactory)
    baz = factory.SubFactory(BazFactory)

这里的愿望是确保发生以下情况

has_bar_and_baz = HasBarAndBazFactory()
has_bar_and_baz.bar.foo === has_bar_and_baz.baz.foo # should be True

我能想到几个解决方案,但我很想知道是否有“ FactoryBoy” 这样的方式,而无需编写接受product_line kwarg的包装函数 并通过它。

我考虑过使用RelatedFactory,然后将其作为子工厂的默认foo引用,但是在基本工厂之后会生成一个RelatedFactory。

2 个答案:

答案 0 :(得分:0)

我尝试了几个失败的解决方案,但是到目前为止,这似乎是行得通的-还可以使用foo kwarg可选的优点,但在我的一些尝试中却不起作用:< / p>

class HasBarAndBazFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = HasBarAndBaz
        exclude = ('foo',)

    foo = factory.SubFactory(FooFactory)
    bar = factory.SubFactory( BarFactory, foo=factory.SelfAttribute('..foo'))
    baz = factory.SubFactory( BazFactory, foo=factory.SelfAttribute('..foo'))

我知道排除,但我不知道您可以声明原始模型中不存在的子工厂属性-我假设必须使用RelatedFactory。

答案 1 :(得分:0)

您有两个选择:将Bar优先于Baz;或公开共享的项目。

第一个选项(用作HasBarAndBazFactory(bar__foo=some_foo)):

class HasBarAndBazFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.HasBarAndBaz

    bar = factory.SubFactory(BarFactory)
    baz = factory.SubFactory(BazFactory, foo=factory.SelfAttribute('..bar.foo'))

第二个选项(用作HasBarAndBazFactory(foo=some_foo)):

class HasBarAndBazFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.HasBarAndBaz

    class Params:
        foo = models.SubFactory(FooFactory)

    bar = factory.SubFactory(BarFactory, foo=factory.SelfAttribute('..foo'))
    baz = factory.SubFactory(BazFactory, foo=factory.SelfAttribute('..foo'))

还没有办法声明bar__foobaz__foo应该始终具有相同的值;您必须在食谱中明确要求。