Django的dumpdata命令存在问题,因为它没有支持任何合理的方法来缩小转储数据的数量。我需要创建各种查询集的fixture(而且我不需要考虑从外部模型关系转储对象)。像django-test-utils makefixture所做的那样限制这些查询集的项目数量是不够的。尝试使用带有自定义管理器的代理模型实现此目的,但这种方法失败了 - dumpdata省略了代理模型(这是合理的)。
Django的dumpdata命令存在问题,因为它没有支持任何合理的方法来缩小转储数据的数量。我需要创建各种查询集的fixture(而且我不需要考虑从外部模型关系转储对象)。像django-test-utils makefixture所做的那样限制这些查询集的项目数量是不够的。尝试使用带有自定义管理器的代理模型实现此目的,但这种方法失败了 - dumpdata省略了代理模型(这是合理的)。
dumpdata
无效,您可以通过Django序列化数据来实现相同的功能。from django.core import serializers
data = serializers.serialize("json", SomeModel.objects.all())
然后将data
写入文件。
from django.core import serializers
from django.core.management.commands.dumpdata import sort_dependencies
app_list = {}
# Add all your querysets here. The key for the dictionary can be just a
# unique dummy string (A safe hack after reading django code)
app_list['app1_name'] = FirstModel.objects.all()
app_list['app2_name'] = SecondModel.objects.all()
# The sort_dependencies will ensure that the models are sorted so that
# those with foreign keys are taken care. If SecondModel has a fk to FirstModel,
# then sort_dependencies will take care of the ordering in the json file so that
# FirstModel comes first in the fixture thus preventing ambiguity when reloading
data = serializers.serialize("json", sort_dependencies(app_list.items()))
f = open('output.json', 'w')
f.write(data)
f.close()
现在输出将会保存在output.json
文件中。要从json文件中重新构建模型:
from django.core import serializers
for obj in serializers.deserialize('json', open('output.json').read()):
obj.save()
编辑: 奇怪的是,sort_dependencies
没有按预期工作。所以我最终使用了 Python 的 ordereddict
并手动决定了顺序。
import collections
app_list = collections.OrderedDict()
如果您想直接将JSON数据保存到文件中,可以使用以下方法:
from django.core import serializers
data = YourModel.objects.all()
with open("fixtures.json", "w") as out:
serializers.serialize("json", data, stream=out)
我不确定你所说的“外部模型关系”是什么意思,也许一个例子会有所帮助,但你可以将你感兴趣的模型传递给dumpdata...
manage.py dumpdata --help
Usage: ./manage.py dumpdata [options] [appname appname.ModelName ...]
还有一个排除开关:
-e EXCLUDE, --exclude=EXCLUDE
An appname or appname.ModelName to exclude (use
multiple --exclude to exclude multiple apps/models).