You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django执行makemigrations时如何仅创建模型并插入一次初始数据

问题根因

你当前的问题根源是:将数据插入的循环逻辑直接写在了models.py的顶层作用域,Django在执行任何命令(包括makemigrations、migrate、runserver等)时都会先加载模型文件,这段代码就会被触发执行,所以每次运行都会重复插入数据。

推荐解决方案:使用Django自定义迁移实现单次初始化

这个方案完全符合Django的设计规范,迁移文件只会被执行一次,不会出现重复插入的问题,步骤如下:

  1. 先删除你现在写在models.py里的countries字典和后续的插入循环代码,避免每次加载模型都触发插入。可以给abbr字段加上唯一约束,从数据库层面避免重复数据:
from django.db import models

class Country(models.Model):
    cid = models.SmallAutoField(primary_key=True)
    label = models.CharField(max_length=100)
    # 加unique约束,从底层避免重复的国家缩写
    abbr = models.CharField(max_length=3, unique=True)
  1. 运行命令生成创建Country表的基础迁移文件:
python manage.py makemigrations <你的App名称>
  1. 运行命令生成一个空的迁移文件,用于写入初始化数据的逻辑:
python manage.py makemigrations <你的App名称> --empty
  1. 打开生成的空迁移文件(路径一般为<你的App名称>/migrations/0002_xxx.py),修改内容如下:
from django.db import migrations

def init_country_data(apps, schema_editor):
    # 注意这里不能直接import你的Country模型,要用apps.get_model获取当前版本的模型
    Country = apps.get_model('<你的App名称>', 'Country')
    countries = {
        "AFG": "Afghanistan",
        "ALB": "Albania",
        "DZA": "Algeria",
        "ASM": "American Samoa",
        "AND": "Andorra",
        "AGO": "Angola",
        "AIA": "Anguilla"
    }
    for abbr, label in countries.items():
        # 只有缩写不存在时才创建数据,双重保险避免重复
        Country.objects.get_or_create(abbr=abbr, defaults={"label": label})

class Migration(migrations.Migration):
    # 依赖前面创建表的迁移文件,这里自动生成的不用改
    dependencies = [
        ('<你的App名称>', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(init_country_data)
    ]
  1. 最后执行迁移命令即可,后续不管运行多少次makemigrations,只要不手动修改这个迁移文件,初始化逻辑只会执行一次:
python manage.py migrate
备选方案:使用fixture加载

如果不需要把初始化逻辑和迁移绑定,也可以用Django的fixture功能:

  • 在你的App下新建fixtures目录,创建countries.json文件写入初始化数据
  • 手动执行一次python manage.py loaddata countries.json即可完成数据插入,不会重复执行。

内容的提问来源于stack exchange,提问作者asprin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:48:04