It’s sometimes useful to pr-populate your database with hard-coded data when you’re first setting up an app. You can provide initial data with fixtures.

1. Create your empty migration:

python manage.py makemigrations --empty <yourapp> --name load_intial_data

2. Edit your migration file <yourapp>/migrations/0002_load_intial_data.py

2.1. Custom implementation, inspired by Django loaddata

import os
from pathlib import Path

from django.db import migrations
from django.core import serializers


current_path = Path().absolute()
fixture_filename = 'initial_data.json'


def load_fixture_user_agent(apps, scheme_editor):
    fixture_file = os.path.join(current_path, '<yourapp>', 'fixtures', fixture_filename )

    with open(fixture_file, 'rb') as fin:
        objects = serializers.deserialize('json', fin, ignorenonexistent=True)
        for obj in objects:
            obj.save()

def unload_fixture_user_agent(apps, scheme_editor):
    'Brutally deleting all entries for this model...'

    MyModel= apps.get_model('youtapp', 'MyModel')
    MyModel.objects.all().delete()


class Migration(migrations.Migration):  

    dependencies = [
        ('yourapp', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_fixture, reverse_code=unload_fixture),
    ]

2.2. A simpler solution for load_fixture

Useful if you want to use a custom directory.

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) 

2.3. Simplest: calling loaddata with app_label will load fixtures from the <yourapp>‘s fixtures dir automatically

from django.core.management import call_command

fixture = 'initial_data'

def load_fixture(apps, schema_editor):
    call_command('loaddata', fixture, app_label='yourapp') 

3. Run it

python manage.py migrate <yourapp>

Leave a Reply

Your email address will not be published.