There are two ways to automatically load data in Django:
- for data you need while running tests, place xml/json/yaml files in
yourapp/fixtures
. - for data you need while setting up the database from scratch, or at specific points in time, you must create a Migration
This is a bit annoying, because chances are these locations will get out of sync sooner or later, and it duplicates effort if you do reproducible builds, docker, and stuff like that.
The solution is to create a migration that actually loads fixtures. So:
- Create your fixtures:
manage.py dumpdata --output yourapp/fixtures/yourmodel.json yourapp.YourModel
- Create an empty Migration:
manage.py makemigrations --empty yourapp
- Edit the resulting migration (the last file created under
yourapp/migrations
, making it look like this:from django.db import migrations def load_fixtures(apps, schema_editor): # This is what will be executed by the migration from django.core.management import call_command # this is the equivalent of running manage.py loaddata yourmodel.json for fixture_name in ['yourmodel']: # add any additional model here call_command("loaddata", fixture_name) # add other calls if you have multiple models def rollback(apps, schema_editor): # This will be executed if you rollback the migration, so you want to clean up for model_name in ["YourModel"]: # add any additional model here model = apps.get_model("yourapp", model_name) model.objects.all().delete() class Migration(migrations.Migration): dependencies = [ # ... don't touch anything here ... ] operations = [ migrations.RunPython(load_fixtures, rollback), ] # -*- coding: utf-8 -*-
- Profit
Note that this does not remove the option to have data that is available only in certain situation: just don't list the fixtures you don't want in the migration, and vice-versa.
No comments:
Post a Comment