夹具¶
另请参阅
什么是夹具?¶
夹具是包含数据库序列化内容的文件集合。每个夹具都有一个唯一的名称,并且构成夹具的文件可以分布在多个目录中,分布在多个应用程序中。
如何生成夹具?¶
夹具可以通过 manage.py dumpdata
生成。还可以通过直接使用 序列化工具 甚至手动编写来生成自定义夹具。
如何使用夹具?¶
夹具可用于预填充数据库数据,用于 测试
class MyTestCase(TestCase):
fixtures = ["fixture-label"]
django-admin loaddata <fixture label>
Django 在哪里查找夹具?¶
Django 将在以下位置搜索夹具
在每个已安装应用程序的
fixtures
目录中在
FIXTURE_DIRS
设置中列出的任何目录中在夹具指定的字面路径中
Django 将加载在这些位置找到的所有与提供的夹具名称匹配的夹具。如果命名夹具具有文件扩展名,则仅加载该类型的夹具。例如
django-admin loaddata mydata.json
将仅加载名为 mydata
的 JSON 夹具。夹具扩展名必须与已注册的 序列化程序 名称相对应(例如,json
或 xml
)。
如果省略扩展名,Django 将搜索所有可用的夹具类型以查找匹配的夹具。例如
django-admin loaddata mydata
将查找任何名为 mydata
的任何类型的夹具。如果夹具目录包含 mydata.json
,则该夹具将作为 JSON 夹具加载。
命名的夹具可以包含目录组件。这些目录将包含在搜索路径中。例如
django-admin loaddata foo/bar/mydata.json
将搜索每个已安装应用程序的 <app_label>/fixtures/foo/bar/mydata.json
,FIXTURE_DIRS
中每个目录的 <dirname>/foo/bar/mydata.json
,以及字面路径 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_save
或 post_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
期间。
压缩夹具¶
夹具可以压缩为 zip
、gz
、bz2
、lzma
或 xz
格式。例如
django-admin loaddata mydata.json
将查找 mydata.json
、mydata.json.zip
、mydata.json.gz
、mydata.json.bz2
、mydata.json.lzma
或 mydata.json.xz
中的任何一个。压缩存档中包含的第一个文件将被使用。
请注意,如果发现两个具有相同名称但不同夹具类型的夹具(例如,如果在同一夹具目录中发现了 mydata.json
和 mydata.xml.gz
),则夹具安装将中止,并且对 loaddata
的调用的任何已安装数据都将从数据库中删除。
使用 MyISAM 的 MySQL 和夹具
MySQL 的 MyISAM 存储引擎不支持事务或约束,因此,如果您使用 MyISAM,则不会获得夹具数据的验证,或者如果发现多个事务文件,则不会回滚。
特定于数据库的夹具¶
如果您处于多数据库设置中,您可能有一些夹具数据希望加载到一个数据库中,但不希望加载到另一个数据库中。在这种情况下,您可以在夹具名称中添加数据库标识符。
例如,如果您的 DATABASES
设置定义了一个 users
数据库,则将夹具命名为 mydata.users.json
或 mydata.users.json.gz
,并且仅当您指定要将数据加载到 users
数据库中时,才会加载该夹具。