2017-07-21 3 views
1

j'ai plusieurs usines avec une structure comme celle-ci:comportement d'héritage incorrect dans les usines de garçon d'usine

AbstractFactoryMinimal(DjangoModelFactory): 
    comment = '' 

AbstractFactoryFull(AbstractFactoryMinimal): 
    comment = Faker(provider='text', max_nb_chars=2000) 

FactoryMinimal(AbstractFactoryMinimal): 
    field = '' 

    class Meta(object): 
     model = SomeModel 

FactoryFull(FactoryMinimal, AbstractFactoryFull): 
    field = Faker(provider='text', max_nb_chars=2000) 

obj = FactoryFull() 
print(obj.comment) # expect some text from faker, but got '' instead 
print(obj.field) # works like expected, return some random text 

Dans les modèles I ont

AbstractModel(TimeStampedModel) 

et

SomeModel(AbstractModel) 

Je regarde même à MRO et il ressemble exactement à ce à quoi je m'attendais:

(FactoryFull, 
FactoryMinimal, 
AbstractFactoryFull, 
AbstractFactoryMinimal, 
factory.django.DjangoModelFactory, 
factory.base.Factory, 
factory.base.BaseFactory, 
object) 

Donc le champ "comment" devrait être généré par faker et pas seulement avec ''. Pourquoi c'est comme ça? Comment puis-je implanter des usines pour voir le comportement attendu?

EDIT: je peux changer l'ordre de succession dans la dernière usine à ceci:

FactoryFull(AbstractFactoryFull, FactoryMinimal) 

il fonctionnera mais, si je veux passer outre champ FactoryMinimal cela ne fonctionnerait pas. Et parfois j'ai besoin exactement de cette fonctionnalité. Et de toute façon, ce n'est pas un comportement d'héritage normal en Python en premier lieu.

Répondre

0

J'ai donc trouvé une solution de contournement.

Fondamentalement, je change l'ordre d'héritage et répète du code. Comme ceci:

FactoryMinimal(AbstractFactoryMinimal): 
    field = '' 

    class Meta(object): 
     model = SomeModel 

FactoryFull(AbstractFactoryFull, FactoryMinimal): 
    field = Faker(provider='text', max_nb_chars=2000) 

    class Meta(object): 
     model = SomeModel 

Et si je dois remplacer quelque chose de la classe de base que j'utilise la classe MixIn pour cela:

CommentFieldMixIn(DjangoModelFactory): 
    comment = 'Something Completely Different' 

FactoryMinimal(AbstractFactoryMinimal): 
    field = '' 

    class Meta(object): 
     model = SomeModel 

FactoryFull(CommentFieldMixIn, AbstractFactoryFull, FactoryMinimal): 
    field = Faker(provider='text', max_nb_chars=2000) 

    class Meta(object): 
     model = SomeModel 

Un seul problème reste: comment je peux dire quelqu'un qui maintiendrait mon code pourquoi Je fais cela dans chaque usine.

0
# Scan the inheritance chain, starting from the furthest point, 
# excluding the current class, to retrieve all declarations. 
for parent in reversed(self.factory.__mro__[1:]): 
    ... 

La raison pour laquelle vous pouvez voir ci-dessus. Vérifiez également le test dans ce commit https://github.com/FactoryBoy/factory_boy/commit/e2ef7c96ed74b35b9dec75a7f222b6ffa9214c10 Je suis dans le doute pourquoi il en est ainsi. Peut-être demander à un auteur de cette bibliothèque sur la motivation?

+0

C'est cool de savoir, mais comment puis-je obtenir le comportement que je veux? –

+0

Puisque vous ne pouvez pas compter sur MRO sans modifier la bibliothèque - évitez d'utiliser l'héritage multiple de cette façon (et mb à tout sauf les mixins). C'est ma seule suggestion. –