2017-06-14 37 views
0

我爲我的模型使用Factory Boy。另一個模型有一個ForeignKey,並且該模型的第一個obj用於模型的字符串表示。例如結構:您可以覆蓋factory_boy的模型函數嗎?

class A(models.Model): 
    ... 

    def __str__(self): 
    return self.reverseForeignKey_set.first().name 

class AFactory(factory.django.DjangoModelFactory): 

    class Meta: 
     model = models.A 

    some_attribute = factory.RelatedFactory(
     ReverseModelFactory, 
     'a', 
     ) 

但是當我使用factory_boy創建,它給了我這個錯誤:

Traceback (most recent call last): 
    File "/home/rahul/Documents/projects/healbot_current/healbot/functional_tests/tests.py", line 21, in setUp 
    factories.AFactory.create() 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 623, in create 
    return cls._generate(True, attrs) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 554, in _generate 
    results[name] = decl.call(obj, create, extraction_context) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/declarations.py", line 624, in call 
    return factory.simple_generate(create, **passed_kwargs) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 709, in simple_generate 
    return cls.generate(strategy, **kwargs) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 676, in generate 
    return action(**kwargs) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 622, in create 
    attrs = cls.attributes(create=True, extra=kwargs) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/base.py", line 449, in attributes 
    utils.log_repr(extra), 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/factory/utils.py", line 142, in log_repr 
    return compat.force_text(repr(obj)) 
    File "/home/rahul/Envs/healbot/lib/python3.6/site-packages/django/db/models/base.py", line 588, in __repr__ 
    u = six.text_type(self) 
    File "/home/rahul/Documents/projects/healbot_current/healbot/diagnosis/models.py", line 57, in __str__ 
    return self.reverseForeignKey_set.first().name 
AttributeError: 'NoneType' object has no attribute 'name' 

有什麼我可以做的來解決這個問題?類似於覆蓋model_b上的str方法僅適用於factory_boy?

回答

0

您有這樣的問題,因爲A模型實例的創建時間早於ReverseModel實例。

作爲factory_boy文件說:

RelatedFactory: this builds or creates a given factory after building/creating the first Factory.

查看所有的http://factoryboy.readthedocs.io/en/latest/reference.html#post-generation-hooks

首先,你應該創建ReverseModel然後你A模型實例。 由於factory_boy文件說,在recepies:

When one attribute is actually a complex field (e.g a ForeignKey to another Model), use the SubFactory declaration

所以,你可以定義一個工廠的FK模型,並把它定義爲在AFactory一個SubFactory。

# models.py 
class A(models.Model): 
    ... 

    def __str__(self): 
     return self.reverseForeignKey_set.first().name 

# factories.py 
import factory 
from . import models 

class ReverseModelFactory(factory.django.DjangoModelFactory): 
    class Meta: 
     model = models.ReverseModel 

     # Define your model fields 
     attr = factory.Faker('text', max_nb_chars=255) 

class AFactory(factory.django.DjangoModelFactory): 
    class Meta: 
     model = models.A 

    some_attribute = factory.SubFactory(ReverseModelFactory) 

在這種情況下,您ReverseModelFactory對象將首先應該解決您的問題產生。 有關更多信息,請參閱http://factoryboy.readthedocs.io/en/latest/recipes.html

我也應該注意,如果你想處理多對多領域,你必須使用post_generation鉤:

# models.py 
class Group(models.Model): 
    name = models.CharField() 

class User(models.Model): 
    name = models.CharField() 
    groups = models.ManyToManyField(Group) 


# factories.py 
class GroupFactory(factory.django.DjangoModelFactory): 
    class Meta: 
     model = models.Group 

    name = factory.Sequence(lambda n: "Group #%s" % n) 

class UserFactory(factory.django.DjangoModelFactory): 
    class Meta: 
     model = models.User 

    name = "John Doe" 

    @factory.post_generation 
    def groups(self, create, extracted, **kwargs): 
     if not create: 
      # Simple build, do nothing. 
      return 

     if extracted: 
      # A list of groups were passed in, use them 
      for group in extracted: 
       self.groups.add(group) 

更多信息請參見http://factoryboy.readthedocs.io/en/latest/recipes.html#simple-many-to-many-relationship

+0

我一直在瀏覽食譜頁面。這部分匹配我的問題:[鏈接](http://factoryboy.readthedocs.io/en/latest/recipes.html#reverse-dependencies-reverse-foreignkey)。但是,如果你用SubFactory替換了RelatedFactory,django將拋出錯誤'Failing row contains(1,name0,null).',因爲你創建了一個沒有外鍵的對象,這就是爲什麼你需要使用RelatedFactory。但是,如果你這樣做,因爲模型A的字符串表示取決於該模型,factory-boy在初始化期間會引發錯誤。 –