The typical way for Django applications to interact with data is through Django models. A Django model is an object orientated Python class that represents the characteristics of an entity. For example, an entity can be a person, a company, a product or some other concept used by an application.
Because data is at the center of modern applications and the Django framework enforces the DRY (Don't Repeat Yourself) principle, Django models often serve as the building blocks for Django projects. Once you have a set of Django models representing an application's entities, Django models can also serve as the basis to simplify the creation of other Django constructs that operate with data (e.g. forms, class-based views, REST services, Django admin pages), hence the importance of Django models as a whole.
In this chapter you'll learn about the core behaviors of Django models, including how to create models and how to use migrations which are central to working effectively with models. Next, you'll learn about the default behaviors of Django models and how to override them with custom behaviors. In addition, you'll learn about the different data types available to create Django models, the different relationships available for Django models and how to manage database transactions with Django models.
Next, you'll learn more about migration files, including the various ways to create migration files, how to rename migration files, how to squash multiple migration files into a single migration file, the meaning behind each migration file element so you can edit migration files with confidence and the procedure to rollback migration files.
In addition, you'll learn about the various Django tools designed to ease the work between Django models and databases, such backing-up and loading model data with fixture files, including how to load initial data into Django models. Next, you'll learn about Django signals which support the software observer pattern in Django models. Finally, you'll finish the chapter learning how to declare Django models outside of their default location, as well as how to configure multiple databases and use them with Django models.
This chapter assumes you've already set up a database for a Django project. If you haven't set up a database, see Chapter 1 on setting up a database for a Django project.
Django models and the migrations workflow
Django's primary storage technology is relational (i.e. out-of-the-box it can connect to SQLite, Postgres, MySQL or Oracle), so a Django model is designed to map directly to a relational database table. This means instances of a Django model are stored as rows of a relational table named after the model.
For example, for a Django model
Store, by default Django performs database
CRUD (Create, Read, Update and Delete) operations on a database
<app_name>_store, where each of the
Store instances represent database rows and a
model's fields (e.g.
state) map to database table
Because Django models revolve
around data, they are prone to change. For example, a Django model
Store can suddenly require the modification of
its original fields due to business requirements (e.g. the addition
of a new field like
these Django models changes throughout time is also an important
aspect of Django models and is managed through the use of migration
Create Django models
Django models are stored in
models.py files located inside Django apps. As soon as
you create a Django app, an empty
models.py file is
added to the app for future use. If you're unfamiliar with the term
Django app, see the Chapter 1 section on setting up Django content.
Listing 7-1 illustrates a sample Django model definition.
Tip Remember the book's code is at https://github.com/drubio/beginningdjango , if you find it easier to follow along with a pre-typed and structured application.
Listing 7-1 Django model class definition in models.py
from __future__ import unicode_literals from django.utils.encoding import python_2_unicode_compatible from django.db import models @python_2_unicode_compatible class Store(models.Model): #id = models.AutoField(primary_key=True)# Added by default, not required explicitly name = models.CharField(max_length=30) address = models.CharField(max_length=30) city = models.CharField(max_length=30) state = models.CharField(max_length=2) #objects = models.Manager()# Added by default, to required explicitly def __str__(self): return "%s (%s,%s)" % (self.name, self.city, self.state)
The first two lines in listing
7-1 import the functionality required to run Python classes in
Django using both Python 2 and Python 3. If your Django project
will just run on Python 3, you can omit these import statements.
The third line in listing 7-1 imports the
django.db.models package which is necessary to access
Django model functionality in the class definition. Next, you can
see the class
Store(models.Model) statement. The
@python_2_unicode_compatible annotation is required to
run the class on Python 2, but if you just use Python 3 you can
omit this annotation.
After the main class definition
in listing 7-1, you can see four fields with the
models.CharField data type which qualifies the fields
as character strings. Further restricting the acceptable values for
each field is the
max_length argument for
indicates the maximum length for the character field is 30
For the moment, don't worry about
models.CharField field definitions. There are many
other data types and arguments supported by Django's
models package, I'll describe all of these options in
the next section on Django model data types.
In addition, notice the Django
model in listing 7-1 has the
objects fields. In this case, I commented them out
# because you don't need to explicitly declare
them, both are automatically added to all Django models, but I put
them there so you know they exist.
id field is a
AutoField data type, that behind the scenes
creates an integer table column that increments automatically. For
example, when you create the first
Store record, the
id field is set to 1 by the database, for the second
Store record the database sets the
field to 2, and so on. The intent of the
id field is
to make record searches easier and more efficient. Because the
id represents a unique number to identify a record,
it's used as a reference, which is also used as a database table's
primary key and as an index to speed up record access. While you
can override various behaviors of this default
field (e.g. change the field name), I'll leave the details of the
id field for a later section and another section on model operations and the importance of the
objects field is
a Django model's default model manager, charged with managing all
the query operations associated with a Django model. Future
sections in this chapter describe the model manager
objects field and the following chapter also describes the use of Django model managers.
Tip If you want to know more about the id field added by default to all Django models: Table 7-1 describes the AutoField data type which is the basis for the id field; the section 'Django model data types' later in this chapter describes the purpose of the primary_key attribute used by the id field; and the save() method described in the 'Model methods' section later in this chapter describes the practical aspects of the id field.
Finally, in listing 7-1 you can
see the class method definition for
__str__ which is a
standard Python method -- part of what are called 'magic methods'
-- that are helpful when attempting to view or print instances of
Django models. The
__str__ method defines a human
readable representation of a class instance (e.g. a
Store model instance based on listing 7-1 is output by
Django model definitions even
when placed in an app's
models.py file still aren't
discoverable by Django. In order for Django to discover model
models.py files, it's necessary to
declare apps as part of the
INSTALLED_APPS variable in
settings.py. Listing 7-2 illustrates an
INSTALLED_APPS definition to discover Django models in
Listing 7-2. Add app to INSTALLED_APPS in Django settings.py to detect models.py definitions
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'coffeehouse.stores', )
As you can see in listing 7-2, in
addition to the default apps declared in
is added at the end. This tells Django to inspect the
models.py file in the
app to take into account any Django model definitions in it.
After the previous steps, an
app's Django model definitions in
models.py are ready
for use. In the next section, I'll describe Django model migrations
and the workflow associated with models in
Migrations and the Django model workflow
Let's start with an illustration of how the Django models workflow operates with migrations thrown into the mix. Figure 7-1 shows the Django models workflow with migrations.
Figure 7-1 Django workflow for models with migrations
Illustrated on the top-left side
of figure 7-1, the workflow starts when you add or modify Django
models on a
models.py file. Once you deem the changes
made to a
models.py file are considerable or want them
reflected on a database, you need to create a migration file.
Migration files provide a step-by-step snapshot of the changes made
models.py file, whether you add, remove or modify
content from the
In order to create migration
files you use the
makemigrations management command.
When you run this command, Django scans the
files for all Django apps declared in
if Django detects a change to a
models.py file, it
creates a new migration file for the app. This process functions
like a version control system, where migration files reflect
changes made to
models.py from a prior a migration
file, and the entire series of migration files tells the whole
evolution of an app's
As you can see in figure 7-1,
migration files are stored in a
sub-directory inside an app, alongside the
file they track. And by default, migration files use the naming
<number_shortdescription> so it's
easy to track in what order they were created and what it's they
Next, lets run
makemigrations on the Django model you created in the
last section. Listing 7-3 illustrates this sequence and adds the
stores argument to limit the migration process to the
stores app -- if you run
without any argument, Django inspects the
for every app in defined in the
Listing 7-3. Django makemigrations command to create migration file for changes made to models.py
[user@coffeehouse ~]$ python manage.py makemigrations stores Migrations for 'stores': 0001_initial.py: - Create model Store
makemigrations stores in listing 7-3, you can see the
0001_initial.py. The file is given this
name because it's the first migration parting from an empty
models.py. Future changes to the
models.py generate migration files named
Turning our attention back the the workflow in figure 7-1, migration files by themselves are just a first step in the Django models workflow. Next, you can either preview or apply these migration files so the models become part of a database.
To preview the actual SQL
statements for a migration before they're applied to a database you
<migration_name> command. Listing 7-4 illustrates the
sqlmigrate sequence for the migration file from the
Listing 7-4. Django sqlmigrate command to preview SQL generated by migration file
[user@coffeehouse ~]$ python manage.py sqlmigrate stores 0001 BEGIN; CREATE TABLE "stores_store" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL, "address" varchar(30) NOT NULL, "city" varchar(30) NOT NULL, "state" varchar(2) NOT NULL); COMMIT;
As you can see in listing 7-4,
the migration file
0001_initial.py for the
stores app is set to run an SQL statement that creates
a database table named
stores_store with field names
that correspond to the Django model from listing 7-1.
Previewing the SQL statements generated by a migration file might not seem too exciting at this stage, but it can be very helpful in other circumstances. For example, if you make complex changes to a Django model or your database is relatively large, it's beneficial to preview the SQL before applying the migration file directly to a database.
Finally, the last step in the
workflow for Django models is to apply the migration files to a
database with the migrate command. Listing 7-5 illustrates this
sequence and adds the
stores argument to limit the
process to the stores app -- if you run
without any argument, Django processes the migration files for
every app in a project.
Listing 7-5 Django migrate command to execute migration files on database
[user@coffeehouse ~]$ python manage.py migrate stores Operations to perform: Apply all migrations: stores Running migrations: Applying stores.0001_initial... OK
In listing 7-5 the
stores.0001_initial migration is run against the
database. This means the SQL presented in listing 7-4 is executed
against the database.
Caution Be careful manipulating the database directly without applying the same changes via Django migrations, as this can lead to inconsistencies and errors.
To keep track of applied
migrations, on the bottom-left side of figure 7-1 you can see the
use of the
showmigrations management command. The
showmigrations command outputs a list of project
migrations, with an X besides those migration files that have been
applied to a database. It's worth mentioning the
showmigrations command obtains its data by inspecting
migration files in
migration folders and the
django_migrations database table that keeps track of