2013-06-20 44 views
4

我刚刚开始使用factory boy和Django。它有一个设置FACTORY_DJANGO_GET_OR_CREATE,这意味着如果已经存在的话它不会创建一个新对象。但是,当我请求一个现有对象与现有的对象时,它会创建一个未使用的对象,尽管此设置。FactoryBoy为什么从SubFactory创建一个新对象,尽管FACTORY_DJANGO_GET_OR_CREATE

例如,在一个全新的项目,我想:

# models.py 
from django.db import models 

class A(models.Model): 
    name = models.CharField(max_length=10) 

class B(models.Model): 
    name = models.CharField(max_length=10) 
    a = models.ForeignKey(A) 

而且

# factories.py 
import factory 

from . import models 

class AFactory(factory.DjangoModelFactory): 
    FACTORY_FOR = models.A 
    FACTORY_DJANGO_GET_OR_CREATE = ('name',) 

    name = factory.Sequence(lambda n: 'A-{0}'.format(n)) 

class BFactory(factory.DjangoModelFactory): 
    FACTORY_FOR = models.B 
    FACTORY_DJANGO_GET_OR_CREATE = ('name',) 

    name = factory.Sequence(lambda n: 'B-{0}'.format(n)) 
    a = factory.SubFactory(AFactory) 

现在:

from factories import * 

a = AFactory(name="Apple") 
models.A.objects.all() 
# one object 
b = BFactory(a__name="Apple", name="Beetle") 
models.B.objects.all() 
models.A.objects.all() 
# one A object, one B object 
b = BFactory(name="Beetle") 
models.B.objects.all() 
models.A.objects.all() 
# still one B object, but now a new, unused A object too 

然后BFactory最后调用带来应运而生类A的新对象,即使B对象与名字甲虫已经存在(并且不被重新创建)。为什么,以及如何阻止正在创建的这个新的A对象?

(我知道我可以调用,而不是解决这个问题:

b = BFactory(name="Beetle", a__name="Apple") 

但在我的实际使用情况,我有几个依赖关系和层次结构的级别,它的杂乱这种方式提供额外的冗余参数 - 我似乎无法得到正确的参数组合)

谢谢!

回答

1

上面是一个问题,当我也有一个C类的外键给B时。新CFactory对象,像这样:

c = CFactory(name="Cat", b__name="Beetle") 

也带来了新的未使用A对象。

我已经找到了解决办法很简单:不是,使新CFactory对象是这样的:

c = CFactory(name="Cat", b=b) 

其中b要么是B对象或BFactory对象。

0

我相信这个子因素不管在get_or_create后面踢什么。

虽然不清楚s9lution,但它不是我遇到的用例。依赖于get_or_create的恕我直导装置具有太多的魔法潜力。如果你有一个复杂的测试用例,替代方案(总是创建)可能会更乏味,但更安全

+0

谢谢!说A是用户,B是帖子。使用上面的代码,如果我创建了新帖子,它总是创建一个新用户并将该帖子与该新用户相关联。我可以使用'工厂男孩'测试一个用户有几个职位? –

+0

我意识到我的评论并不清楚 - 如果您像上面所做的那样设置FACTORY_DJANGO_GET_OR_CREATE,那么有几个帖子的用户很容易。但我确实有用户拥有企业,而企业发布帖子(即有第三类C)。实际上,其他对象也可以使用'ForeignKeys'(类D,E ...)。所以每次我创建这些下游对象时,我都会得到一个新创建(和未使用)对象的整个层次结构。这是我想避免的。 –

1

你可以把使用:

a = SubFactory(AFactory, name='Reuse this model A instance') 

这样,下面的两个调用都是平等的:

BFactory() 
BFactory(a__name='Reuse this model A instance') 
相关问题