在 Django Factory Boy 中,是否可以为某个实例指定自定义 FactoryOptions?
In Django Factory Boy, is it possible to specify custom FactoryOptions for a certain instance?
我正在为使用 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
class 中指定的选项将适用于 所有 个实例,而我只希望它只适用于这个实例。是否可以在构造函数中指定这些选项?
仔细阅读源代码后,从 DjangoModelFactory
class 定义中的 this line 看来,这是不可能的。 class 包含以下 class 方法:
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
似乎是一个 class 属性而不是实例属性,因此不可能为每个实例指定 django_get_or_create
。如有错误请指正!
文档有点误导。 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)
。
由于您在 title
字段上有一个 unique
条件,您可以安全地将该行为放置在 SessionTypeFactory
级别。
我正在为使用 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
class 中指定的选项将适用于 所有 个实例,而我只希望它只适用于这个实例。是否可以在构造函数中指定这些选项?
仔细阅读源代码后,从 DjangoModelFactory
class 定义中的 this line 看来,这是不可能的。 class 包含以下 class 方法:
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
似乎是一个 class 属性而不是实例属性,因此不可能为每个实例指定 django_get_or_create
。如有错误请指正!
文档有点误导。 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)
。
由于您在 title
字段上有一个 unique
条件,您可以安全地将该行为放置在 SessionTypeFactory
级别。