Skip to main content

Models & Migrations

Create and update models

To create a new model, you have to create a new class in the models.py file of an app.

models.py
from django.db import models

from apps.student.models import Student

class Event(models.Model):
title = models.CharField(max_length=100)
begin_date = models.DateTimeField("Début")
end_date = models.DateTimeField("Fin")
publisher = models.ForeignKey(to=Student, on_delete=models.CASCADE)
Important note

After creating or updating a model, you must update the database!

Now we need to update the database. First, let's create a migration file:

pipenv run makemigrations [app_name]

Then, apply the migration on your own database:

pipenv run migrate
Why migration files are important?

A migration files describe how to move the database from the previous structure to the new structure you described in your models. Without a migration file, all data will be erased each time you update the models, which is not really what we want! 😱

Most of the time, Django is smart enough to migrate the data without loss. But in some cases, the migration can be more complicated and you have to write the migration file yourself to avoid any data loss!

See More on migrations for more details.

Learn more on models and fields in the official documentation.

Query objects

In your view, you will often need to query objects from the database. Here are some examples of how to do it:

from .models import Event

def my_view(request):
# Get one event
my_event = Event.objects.get(id=2)
# Get all events
event_list = Event.objects.all()

# Get events after a specific date
recent_events = Event.objects.filter(begin_date__gte="2021-01-01")
# or re-use the previous query
recent_events = event_list.filter(begin_date__gte="2021-01-01")

# Get events from a specific publisher
current_student = request.user.student
published_events = Event.objects.filter(publisher=current_student)
# or use the reverse relation
published_events = current_student.event_set.all()

Learn more on queries in the official documentation.

More on migrations

Good practices

  • Try to merge migration files into one file as much as possible: we try to have as few migration files as possible. To do so, un-apply your last migrations files, delete them, and recreate a new migration file.
    Be careful

    You can't change migration files once they are uploaded to the master branch on the server.

Applying and un-applying migrations

Let's suppose you have an app called event, with 5 files. Only the first 2 migrations are applied on your database:

0001_initial.py                  # already applied on your database
0002_auto_20200626_2132.py # already applied on your database
0003_auto_social_network_init.py # not applied
0004_move_social_network.py # not applied
0005_move_liste.py # not applied

Now you can do multiple things:

  • If you want to apply all migrations (3, 4 and 5):
    pipenv run migrate event
  • If you want to apply only migrations 3 and 4, but not 5:
    pipenv run migrate event 0004
  • If you want to un-apply the migration n°2, and return to the state after the migration n°1:
    pipenv run migrate event 0001

Writing a custom migration

You can write custom migrations, for example to transfer or copy data from one table to another.

First, create an empty migration file with:

pipenv run makemigrations <app_name> --empty --name <file_name>

Then, go to the migrations directory, and edit the new created file to implement your custom migrations.

You can find examples of custom migrations by searching for RunPython in the Nantral Platform code. You can also use the django documentation to know how to write custom migrations.