一次加载多个夹具
有没有办法加载一个灯具并让它加载多个灯具?
理想情况下,我想输入:
python manage.py loaddata all_fixtures
并加载所有数据,而不必输入所有内容。这可能吗?
Is there anyway to load one fixture and have it load multiple fixtures?
I'd ideally like to type:
python manage.py loaddata all_fixtures
And have that load all of the data instead of having to type everything. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(12)
该线程显示在 Google 搜索“从所有灯具加载数据”的第一个结果中,并且没有提及 IMO 对此的正确解决方案是什么,即允许您加载任何您想要的灯具而无需任何灯具的解决方案通配符技巧或对settings.py文件进行一次修改(我也曾经这样做过)
只需使应用程序的固定装置目录平坦(而不是通常的Django方案,例如app_name / templates / app_name / mytemplate.html),即 app_name/fixtures/myfixture.[json, yaml, xml]
这是 django doc 说:
例如:
django-admin loaddata foo/bar/mydata.json
将在 /fixtures/foo/bar/mydata.json 中搜索每个已安装的应用程序,在 /foo/bar/mydata.json 中搜索 FIXTURE_DIRS 中的每个目录,并在文字路径 foo/bar/mydata.json 中搜索。
这意味着,如果您的所有应用程序目录中都有固定装置/myfixture.json,则只需运行即可
./manage.py loaddata myfixture
加载项目中位于该处的所有固定装置......就是这样!您甚至可以使用 --app 或 --exclude 参数来限制加载设备的应用程序。
我会提到,我在进行一些开发时仅使用我的装置来填充我的数据库,所以我不介意在我的“装置”目录中有一个平面结构......但即使你使用你的装置进行测试,它似乎也有扁平结构是 Django 式的方式,并且
该答案表明,您只需编写以下内容即可引用特定应用程序中的装置:
class MyTestCase(TestCase):
fixtures = ['app_name/fixtures/myfixture.json']
为什么不创建一个 Makefile 来引入所有的装置呢?例如:
load_all_fixtures:
./manage.py loaddata path/to/fixtures/foo.json
./manage.py loaddata path/to/fixtures/bar.json
./manage.py loaddata path/to/fixtures/baz.json
然后在 shell 提示符下运行
make load_all_fixtures
(这种方法也适用于仅对某些应用程序执行单元测试,并在需要时忽略其他应用程序)
如果你想在 Linux 和 Windows 上使用此功能,你只需使用它来加载所有 json-Fixtures:
import os
files = os.listdir('path/to/my/fixtures')
def loaddata(file):
if os.path.splitext(file)[1] == '.json' and file != 'initial_data.json':
print file
os.system("python manage.py loaddata %s" % file)
map(loaddata, files)
如果您的装置位于同一文件夹中,您只需 ls
和 xargs
:ls myfolder | xargs django-admin loaddata
。
此结构的示例:
$ tree fixtures/
root_dir/fixtures/
├── 1_users.json
├── 2_articles.json
└── 3_addresses.json
$ ls -d fixtures/* | xargs django-admin loaddata
将执行与以下相同的操作:
$ django-admin loaddata 1_users.json
$ django-admin loaddata 2_articles.json
$ django-admin loaddata 3_addresses.json
经过一番搜索后,我最终编写了这个脚本。它在所有名为“fixtures”的目录中搜索 .json 文件并运行“python manage.py loaddata {fixture_name}.json”。有时,顺序对于外键约束很重要,因此如果无法解决约束,则会在队列中留下固定装置。
(注意:它需要我编写的 pip 包 simple_terminal 。并且我将其设置为由“python manage.py runscript ”运行,这需要 django-extensions。)
# load_fixture.py
#
# A script that searches for all .json files in fixtures directories
# and loads them into the working database. This is meant to be run after
# dropping and recreating a database then running migrations.
#
# Usage: python manage.py runscript load_fixtures
from simple_terminal import Terminal
from django.core.management import call_command
from django.db.utils import IntegrityError
def load_fixture(fixture_location):
# runs command: python manage.py loaddata <fixture_location>
call_command('loaddata', fixture_location)
def run():
with Terminal() as t:
# get all .json files in a fixtures directory
fixture_locations = t.command(
'find . -name *.json | grep fixtures | grep -v env')
while fixture_locations:
# check that every iteration imports are occuring
errors = []
length_before = len(fixture_locations)
for fl in fixture_locations:
try:
# try to load fixture and if loaded remove it from the array
load_fixture(fl)
print("LOADED: {}".format(fl))
fixture_locations.remove(fl)
except IntegrityError as e:
errors.append(str(e))
# if import did not occur this iteration raise exception due to
# missing foreign key reference
length_after = len(fixture_locations)
if length_before == length_after:
raise IntegrityError(' '.join(errors))
python manage.py loaddata ./*/fixtures/*.json
此命令将在所有目录中查找文件夹 fixture
,然后它将拾取所有带有 json
扩展名的文件并安装装置。
这样,您就不必只有一个固定装置文件夹,而是可以在应用程序级别和多个应用程序中拥有固定装置。
它将与像这样的理想文件夹结构一起使用 -
app_name_1
├──fixtures
├────json_file_1.json
├────json_file_2.json
app_name_2
├──fixtures
├────json_file_3.json
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用 $ python manage.py loaddata myfixtures/*.json 可以正常工作,因为 Bash 会将通配符替换为匹配文件名列表。
Using
$ python manage.py loaddata myfixtures/*.json
would work as Bash will substitute the wildcard to a list of matching filenames.