在 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 级别。