20
Set up and Load Initial Data in Django
Introduction
Sometimes there's a need to have a set of initial data once we spin up our application. Reasons vary, but the need is there. Django provides two ways of setting up and loading this initial data to our database.
- Using Fixtures
- Using Migrations
For the purposes of this brief explanation, we will have a model, Book in our app called Main
# main/models.py
from django import models
class Book(models.Model):
name = models.CharField(max_length=50)
author = models.CharField(max_length=20)
A fixture is a collection of data that Django knows how to import into a database. In this specific approach to fixtures, our data is not going to be loaded automatically. We are going to create the fixture by hand, then load them by running a command.
First, we need a folder to hold our fixtures. We can create a folder called fixtures
at app level (in our app Main), or we can have all our fixtures at project level by defining FIXTURE_DIRS
in our settings.py
.
FIXTURE_DIRS should contain a list of directories where Django should look for fixtures.
In this case, I have set FIXTURE_DIRS at project level to have it as:
# my_project/setting.py
FIXTURE_DIRS = BASE_DIR / "fixtures"
Create the directory fixtures
at project level. Here, we are going to create our fixtures, which can be any of the following formats:
- JSON
- XML
- YAML
We are going to use JSON, so within our fixtures directory, let's create a file book.json
. I prefer to name the fixtures after the app that their models belong to.
# fixtures/cars.json
[
{
"model": "main.book",
"pk": 1,
"fields": {
"name": "Atomic Habits",
"author": "James Clear",
}
},
{
"model": "main.book",
"pk": 2,
"fields": {
"name": "Permanent Record",
"author": "Edward Snowden",
}
}
]
Since we have created our fixtures by hand, we need to call the individually to load the data:
python manage.py loaddata fixture_file_name
python manage.py loaddata cars.json
In this method, we are going to generate our own empty migration by running the following command:
syntax: python manage.py makemigrations --empty appname
As previously mentioned, our app name is Main, and our model is Book, so our command should be:
python manage.py makemigrations --empty main
This command will generate an automatically migration file, within your app's migrations folder. The file should be of a similiar format to this:
# Generated by Django 3.0.11 on 2021-12-15 08:35
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0001_initial'),
]
operations = [
]
We need to create a function that will add the data. This function must have two arguments, which are:
App Registry - A registry of all your apps, including
historical versions of their models.Schema Editor - This is what is used to manually
effect database schema changes, (enforce changes to database)
With this is in mind, let's write our function:
def load_initial_data(apps, schema_editor):
# get our model
# get_model(appname, modelname)
book_model = apps.get_model('main', 'Book')
book_model.objects.create (
name = "Atomic Habits", author = "James Clear"
)
book_model.objects.create (
name = "Permanent Record", author = "Edward Snowden"
)
This function should be within your migration file, as follows:
# Generated by Django 3.0.11 on 2021-12-15 08:35
from django.db import migrations
def load_initial_data(apps, schema_editor):
# get our model
# get_model(appname, modelname)
book_model = apps.get_model('main', 'Book')
book_model.objects.create (
name = "Atomic Habits", author = "James Clear"
)
book_model.objects.create (
name = "Permanent Record", author = "Edward Snowden"
)
class Migration(migrations.Migration):
dependencies = [
('main', '0001_initial'),
]
operations = [
]
We can now add our load_initial_data
function to the operations
list in our migration file:
operations = [
migrations.RunPython(load_initial_data),
]
Your complete migrations file should be similar to this:
# Generated by Django 3.0.11 on 2021-12-15 08:35
from django.db import migrations
def load_initial_data(apps, schema_editor):
# get our model
# get_model(appname, modelname)
book_model = apps.get_model('main', 'Book')
book_model.objects.create (
name = "Atomic Habits", author = "James Clear"
)
book_model.objects.create (
name = "Permanent Record", author = "Edward Snowden"
)
class Migration(migrations.Migration):
dependencies = [
('main', '0001_initial'),
]
operations = [
migrations.RunPython(load_initial_data),
]
Since our data is in a migration file, we need to migrate in order to load it. So, we simply run:
python manage.py migrate
20