Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create per-project initial_data fixtures in Django 1.7+

Before Django 1.7 I used to define a per-project fixtures directory in the settings:

FIXTURE_DIRS = ('myproject/fixtures',)

and use that to place my initial_data.json fixture storing the default groups essential for the whole project. This has been working well for me as I could keep the design clean by separating per-project data from app-specific data.

Now with Django 1.7, initial_data fixtures have been deprecated, suggesting to include data migrations together with app's schema migrations; leaving no obvious choice for global per-project initial data.

Moreover the new migrations framework installs all legacy initial data fixtures before executing migrations for the compliant apps (including the django.contrib.auth app). This behavior causes my fixture containing default groups to fail installation, since the auth_group table is not present in the DB yet.

Any suggestions on how to (elegantly) make fixtures run after all the migrations, or at least after the auth app migrations? Or any other ideas to solve this problem? I find fixtures a great way for providing initial data and would like to have a simple and clean way of declaring them for automatic installation. The new RunPython is just too cumbersome and I consider it an overkill for most purposes; and it seems to be only available for per-app migrations.

like image 681
knaperek Avatar asked Sep 13 '14 15:09

knaperek


People also ask

How to write fixtures in Django?

You must create a directory in your app named fixtures and put your fixtures files there. You can write them in json or xml, one easy way to make them is to create some objects in the admin interface and then run manage.py dumpdata. That would dump the data from the objects you created into fixture files.

Where to place fixtures in Django?

You'll store this data in a fixtures directory inside your app. You can load data by calling manage.py loaddata <fixturename> , where <fixturename> is the name of the fixture file you've created. Each time you run loaddata , the data will be read from the fixture and reloaded into the database.


1 Answers

If you absolutely want to use fixtures, just use RunPythonand call_command in your data migrations.

from django.db import migrations
from django.core.management import call_command

def add_data(apps, schema_editor):
    call_command('loaddata', 'thefixture.json')

def remove_data(apps, schema_editor):
    call_command('flush')


class Migration(migrations.Migration):

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

    operations = [
        migrations.RunPython(
            add_data,
            reverse_code=remove_data),
    ]

However this is recommanded to load data using python code and Django ORM, as you won't have to face integrity issues.

Source.

like image 180
Antwan Avatar answered Sep 22 '22 15:09

Antwan