2013-06-20 4 views
4

방금 ​​장고에서 factory boy을 사용하기 시작했습니다. 그것은 FACTORY_DJANGO_GET_OR_CREATE이라는 설정을 가지고 있습니다. 즉, 이미 존재하는 경우 새 개체를 만들지 않습니다. 그러나 기존 SubFactory 개체가있는 개체를 요청하면이 설정에도 불구하고 사용되지 않은 개체가 만들어집니다.FactoryBoy가 FACTORY_DJANGO_GET_OR_CREATE에도 불구하고 SubFactory에서 새로운 객체를 만드는 이유

예를 들어, 새로운 프로젝트에, 나는 시도 :

# 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의 name Beetle은 이미 존재하며 다시 생성되지 않습니다. 왜, 그리고 어떻게이 새로운 A 객체가 생성되는 것을 멈추게합니까?

은 (내가 대신 호출하여이 문제를 얻을 수 있습니다 알고

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

하지만 내 실제 사용의 경우, 나는 여러 종속성 및 계층 구조의 수준이, 그리고이 방법을 추가 중복 매개 변수를 제공하는 혼란의

- 매개 변수의 올바른 조합을 얻을 수없는 것 같습니다.)

고마워!

답변

1

위의 것은 B에 외래 키가있는 클래스 C를 가지고있을 때 문제가된다. 그래서 같은 새로운 CFactory 객체 :

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

그것은 또한 새로운 사용되지 않는 A 개체를 만듭니다.

나는이에 대한 해결책은 간단하다 발견 : 대신,이 같은 새로운 CFactory 개체를 만들 :

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

bB 개체 또는 BFactory 개체 중 하나입니다.

0

나는 get_or_create 이후에 후속 공격이 일어날 것이라고 생각합니다.

확실하지는 않지만 필자가 만난 유스 케이스는 아닙니다. get_or_create에 의존하는 IMHO 비품에는 너무 많은 잠재력이 있습니다. 당신이 복잡한 테스트 케이스를 가지고 있지만 더 안전하다면 대안 (항상 생성)은 좀 지루할 수있다.

+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')