固定装置

参见

什么是固定装置?

A fixture 是包含数据库的序列化内容的文件集合。每个装置都有一个唯一的名称,并且组成装置的文件可以分布在多个应用程序中的多个目录中。

如何制作夹具?

装置可以通过以下方式生成 manage.py dumpdata 。还可以通过直接使用生成定制灯具 serialization tools 甚至是手写的。

如何使用灯具?

装置可用于使用以下各项的数据预先填充数据库 tests

class MyTestCase(TestCase):
    fixtures = ["fixture-label"]

或者提供一些 initial data 使用 loaddata 命令:

django-admin loaddata <fixture label>

姜戈在哪里寻找固定装置?

Django将在以下位置搜索灯具:

  1. fixtures 每个已安装应用程序的目录

  2. 中列出的任何目录中 FIXTURE_DIRS 设置

  3. 在由装置命名的文字路径中

Django将加载它在这些位置找到的与提供的装置名称匹配的任何和所有装置。如果命名的装置具有文件扩展名,则只会加载该类型的装置。例如:

django-admin loaddata mydata.json

将仅加载名为 mydata 。装置扩展名必须对应于 serializer (例如, jsonxml )。

如果省略扩展名,Django将在所有可用的装置类型中搜索匹配的装置。例如:

django-admin loaddata mydata

将查找任何装置类型为 mydata 。如果某个装置目录包含 mydata.json ,则该装置将作为JSON装置加载。

命名的装置可以包括目录元件。这些目录将包含在搜索路径中。例如:

django-admin loaddata foo/bar/mydata.json

会去搜索 <app_label>/fixtures/foo/bar/mydata.json 对于每个安装的应用程序, <dirname>/foo/bar/mydata.json 对于中的每个目录 FIXTURE_DIRS ,和文字路径 foo/bar/mydata.json

装置加载顺序

可以在同一调用中指定多个装置。例如:

django-admin loaddata mammals birds insects

或者在测试用例类中:

class AnimalTestCase(TestCase):
    fixtures = ["mammals", "birds", "insects"]

装入装置的顺序遵循它们被列出的顺序,无论是在使用管理命令时还是在如上所示的测试用例类中列出它们时。

在这些示例中,所有名为 mammals 从所有应用程序(按中定义应用程序的顺序 INSTALLED_APPS )将首先加载。随后,所有的 birds 将加载设备,然后加载所有 insects 固定装置。

请注意,如果数据库后端支持行级约束,则将在事务结束时检查这些约束。如果数据库配置不支持延迟约束检查,则跨装置的任何关系都可能导致加载错误(请参阅 MySQL 文档作为一个例子)。

如何将夹具保存到数据库?

处理装置文件时,数据将按原样保存到数据库。定义的模型 save() 方法不被调用,并且任何 pre_savepost_save 信号将被调用 raw=True 因为该实例只包含模型的本地属性。例如,您可能希望禁用访问在装置加载过程中不存在的相关字段的处理程序,否则将引发异常::

from django.db.models.signals import post_save
from .models import MyModel


def my_handler(**kwargs):
    # disable the handler during fixture loading
    if kwargs["raw"]:
        return
    ...


post_save.connect(my_handler, sender=MyModel)

您还可以编写一个修饰符来封装此逻辑::

from functools import wraps


def disable_for_loaddata(signal_handler):
    """
    Decorator that turns off signal handlers when loading fixture data.
    """

    @wraps(signal_handler)
    def wrapper(*args, **kwargs):
        if kwargs["raw"]:
            return
        signal_handler(*args, **kwargs)

    return wrapper


@disable_for_loaddata
def my_handler(**kwargs):
    ...

只需注意,此逻辑将在装备被反序列化时禁用信号,而不仅仅是在 loaddata

压缩固定装置

固定装置可以压缩为 zipgzbz2lzma ,或 xz 格式化。例如:

django-admin loaddata mydata.json

会寻找任何一种 mydata.jsonmydata.json.zipmydata.json.gzmydata.json.bz2mydata.json.lzma ,或 mydata.json.xz 。使用压缩存档中包含的第一个文件。

请注意,如果发现两个名称相同但设备类型不同的设备(例如,如果 mydata.jsonmydata.xml.gz 都在同一个Fixture目录中找到),则将中止Fixture安装,并且调用中安装的所有数据 loaddata 将从数据库中删除。

带有MyISAM和装置的MySQL

MySQL的MyISAM存储引擎不支持事务或约束,所以如果您使用MyISAM,您将不会得到装置数据的验证,或者如果找到多个事务文件,则不会进行回滚。

特定于数据库的装置

如果您处于多数据库设置中,则可能需要将装置数据加载到一个数据库中,而不是加载到另一个数据库中。在这种情况下,您可以在装置的名称中添加数据库标识符。

例如,如果您的 DATABASES 设置有一个 users 数据库已定义,请为该装置命名 mydata.users.jsonmydata.users.json.gz 并且仅当您指定要将数据加载到 users 数据库。