我正在为使用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 实例,而我只希望适用于此实例。可以在构造函数中指定这些选项吗?
答案 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
。如果我错了,请纠正我!