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.
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)
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
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.