在Django Factory Boy中,是否可以为特定实例指定自定义FactoryOptions?

时间:2018-07-11 16:40:43

标签: python django database factory-boy

我正在为使用factory_boy测试夹具的Django应用编写单元测试。在某些情况下,一个装置可能会尝试创建一个已经由另一个装置创建的对象,这会导致类似于以下内容的错误消息:

django.db.utils.IntegrityError: duplicate key value violates unique constraint "lucy_web_sessiontype_title_c207e4f8_uniq"
DETAIL:  Key (title)=(Postpartum Doula Support) already exists.

为避免这种情况,我的第一个倾向是编写一个try..except块,如下所示:

try:
    SessionTypeFactory(title='Welcome')
except psycopg2.IntegrityError as e:
    pass

但是,使用http://factoryboy.readthedocs.io/en/latest/orms.html#factory.django.DjangoOptions.django_get_or_create中所述的django_get_or_create选项似乎更为优雅。

但是,据我从http://factoryboy.readthedocs.io/en/latest/reference.html#factory.FactoryOptions得知,工厂的Meta类中指定的选项将应用于 all 实例,而我只希望适用于此实例。可以在构造函数中指定这些选项吗?

2 个答案:

答案 0 :(得分:2)

该文档有些误导。 FactoryOptions部分记录的是class Meta部分中可用的选项列表。

在您的情况下,您可以使用以下代码示例:

class SessionTypeFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.SessionType
        django_get_or_create = ['title']

    # your fields here

每次创建实例时,这将执行SessionType.objects.get_or_create(title=fields.pop('title'), defaults=fields)。 由于您在unique字段上有一个title条件,因此可以在SessionTypeFactory级别放心地执行该行为。

答案 1 :(得分:0)

在仔细阅读源代码之后,在.outer类定义中的this line看来这是不可能的。该类包含以下类方法:

DjangoModelFactory

由此看来,class DjangoModelFactory(base.Factory): @classmethod def _create(cls, model_class, *args, **kwargs): """Create an instance of the model, and save it to the database.""" manager = cls._get_manager(model_class) if cls._meta.django_get_or_create: return cls._get_or_create(model_class, *args, **kwargs) return manager.create(*args, **kwargs) 是类属性而不是实例属性,因此不可能为每个实例指定django_get_or_create。如果我错了,请纠正我!