I recently switched from Django 1.6 to 1.7, and I began using migrations (I never used South).

在1.7之前,我用fixture/initial_data.json文件加载初始数据,该文件是用python manage.py syncdb命令加载的(在创建数据库时).

现在,我开始使用迁移,此行为已弃用:

If an application uses migrations, there is no automatic loading of fixtures. Since migrations will be required for applications in Django 2.0, this behavior is considered deprecated. If you want to load initial data for an app, consider doing it in a data migration. (https://docs.djangoproject.com/en/1.7/howto/initial-data/#automatically-loading-initial-data-fixtures)

The official documentation does not have a clear example on how to do it, so my question is :

使用数据迁移导入此类初始数据的最佳方式是什么:

  1. Write Python code with multiple calls to mymodel.create(...),
  2. Use or write a Django function (like calling loaddata) to load data from a JSON fixture file.

我更喜欢第二种选择.

I don't want to use South, as Django seems to be able to do it natively now.

推荐答案

Update:有关此解决方案可能导致的问题,请参阅下面@GwynBleidD的评论,并参阅下面@Rockallite的答案,以了解对future 模型更改更持久的方法.


假设你有一个<yourapp>/fixtures/initial_data.json英寸的fixture 文件

  1. Create your empty migration:

    In Django 1.7:

    python manage.py makemigrations --empty <yourapp>
    

    In Django 1.8+, you can provide a name:

    python manage.py makemigrations --empty <yourapp> --name load_intial_data
    
  2. Edit your migration file <yourapp>/migrations/0002_auto_xxx.py

    2.1. Custom implementation, inspired by Django' loaddata (initial answer):

    import os
    from sys import path
    from django.core import serializers
    
    fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures'))
    fixture_filename = 'initial_data.json'
    
    def load_fixture(apps, schema_editor):
        fixture_file = os.path.join(fixture_dir, fixture_filename)
    
        fixture = open(fixture_file, 'rb')
        objects = serializers.deserialize('json', fixture, ignorenonexistent=True)
        for obj in objects:
            obj.save()
        fixture.close()
    
    def unload_fixture(apps, schema_editor):
        "Brutally deleting all entries for this model..."
    
        MyModel = apps.get_model("yourapp", "ModelName")
        MyModel.objects.all().delete()
    
    class Migration(migrations.Migration):  
    
        dependencies = [
            ('yourapp', '0001_initial'),
        ]
    
        operations = [
            migrations.RunPython(load_fixture, reverse_code=unload_fixture),
        ]
    

    2.2. load_fixture美元的简单解决方案(根据@juliocesar的建议):

    from django.core.management import call_command
    
    fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures'))
    fixture_filename = 'initial_data.json'
    
    def load_fixture(apps, schema_editor):
        fixture_file = os.path.join(fixture_dir, fixture_filename)
        call_command('loaddata', fixture_file) 
    

    Useful if you want to use a custom directory.

    2.3. Simplest:app_label呼叫loaddata将自动从<yourapp>fixtures dir加载装置:

    from django.core.management import call_command
    
    fixture = 'initial_data'
    
    def load_fixture(apps, schema_editor):
        call_command('loaddata', fixture, app_label='yourapp') 
    

    If you don't specify app_label, loaddata will try to load fixture filename from all apps fixtures directories (which you probably don't want).

  3. 运行它

Json相关问答推荐

boost::json::value 的大括号初始化将其从对象转换为数组

如何使用 jq 返回此 JSON 文件的“文本”字段?

使用 jq 将键值行转换为 json

如何在 onClick 事件处理程序中识别在同一 map 上绘制的多个多边形中的哪个(使用 react-leaflet)被单击?

Microsoft GRAPH 查询使用端点 /deviceManagement/deviceHealthScripts 列出了一种不熟悉的检测脚本内容格式

如何在 Django 的模板语言中获取 json 键和值?

无法向 Json 数组添加新元素

JSON.parse 返回字符串而不是对象

在 TypeScript 中导入 JSON 文件

将对象转换为可编码对象失败

将 JSON 读取到 pandas 数据框 - ValueError:将 dicts 与非系列混合可能会导致排序不明确

如何使用 jq 将字符串转换为 JSON 文件中的整数?

使用 Bash 变量构建 JSON 字符串

Kubernetes / kubectl - “必须指定容器名称”但看起来是这样吗?

dump() 缺少 1 个必需的位置参数:python json 中的“fp”

如何使用 Serde 使用顶级数组反序列化 JSON?

如何在 Json.NET 中将巨大的 JSON 文件解析为流?

使用 jq 如何用其他名称替换键的名称

处理响应 - SyntaxError:使用模式时输入意外结束:'no-cors'

使用电源查询的 Json excel