你可以覆盖factory_boy的模型函数吗?

时间:2017-06-14 15:09:59

标签: python django factory-boy

我使用Factory boy作为我的模特。另一个模型有一个ForeignKey,该模型的第一个obj用于模型的字符串表示。示例结构:

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'

我能做些什么来解决这个问题吗?就像在Factory_boy上覆盖模型A上的 str 方法一样?

1 个答案:

答案 0 :(得分:0)

您遇到此类问题,因为A模型实例的创建时间早于ReverseModel实例。

正如factory_boy文档所说:

  

RelatedFactory:在构建/创建第一个Factory之后构建或创建一个给定的工厂。

请参阅http://factoryboy.readthedocs.io/en/latest/reference.html#post-generation-hooks

首先,您应该创建ReverseModel,然后创建A模型实例。 正如factory_boy文档在接收中所说:

  

当一个属性实际上是一个复杂的字段(例如,另一个Model的ForeignKey)时,请使用SubFactory声明

因此,您可以为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

我还应该注意,如果你想处理ManyToMany字段,你应该使用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

相关问题