Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Web Development with Django
Web Development with Django

Web Development with Django: Learn to build modern web applications with a Python-based framework

Arrow left icon
Profile Icon Ben Shaw Profile Icon Saurabh Badhwar Profile Icon Bird Profile Icon Bharath Chandra K S Profile Icon Chris Guest +1 more Show less
Arrow right icon
$69.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4 (36 Ratings)
Paperback Feb 2021 826 pages 1st Edition
eBook
$49.99 $55.99
Paperback
$69.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Ben Shaw Profile Icon Saurabh Badhwar Profile Icon Bird Profile Icon Bharath Chandra K S Profile Icon Chris Guest +1 more Show less
Arrow right icon
$69.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4 (36 Ratings)
Paperback Feb 2021 826 pages 1st Edition
eBook
$49.99 $55.99
Paperback
$69.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$49.99 $55.99
Paperback
$69.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Web Development with Django

2. Models and Migrations

Overview

This chapter introduces you to the concept of databases and their importance in building web applications. You will start by creating a database using an open-source database visualization tool called SQLite DB Browser. You will then perform some basic Create Read Update Delete (CRUD) database operations using SQL commands. Then, you will learn about Django's Object Relational Mapping (ORM), using which your application can interact and seamlessly work with a relational database using simple Python code, eliminating the need to run complex SQL queries. You will learn about models and migrations, which are a part of Django's ORM, that are used to propagate database schematic changes from the application to the database, and also perform database CRUD operations. Toward the end of the chapter, you will study the various types of database relationships and use that knowledge to perform queries across related records.

Introduction

Data is at the core of most web applications. Unless we're talking about a very simple application such as a calculator, in most cases we need to store data, process it, and display it to the user on a page. Since most operations in user-facing web applications involve data, there is a need to store data in places that are secure, easily accessible, and readily available. This is where databases come in handy. Imagine a library operational before the advent of computers. The librarian would have to maintain records of book inventories, records of book lending, returns from students, and so on. All of these would have been maintained in physical records. The librarian, while carrying out their day-to-day activities, would modify these records for each operation, for example, when lending a book to someone or when the book was returned.

Today, we have databases to help us with such administrative tasks. A database looks like a spreadsheet or an Excel sheet containing records, with each table consisting of multiple rows and columns. An application can have many such tables. Here is an example table of a book inventory in a library:

Figure 2.1: Table of a book inventory for a library

Figure 2.1: Table of a book inventory for a library

In the preceding table, we can see that there are columns with details about various attributes of the books in the library, while the rows contain entries for each book. To manage a library, there can be many such tables working together as a system. For example, along with an inventory, we may have other tables such as student information, book lending records, and so on. Databases are built with the same logic, where software applications can easily manage data.

In the previous chapter, we had a brief introduction to Django and its use in developing web applications. Then we learned about the Model-View-Template (MVT) concept. Later, we created a Django project and started the Django development server. We also had a brief discussion about Django's views, URLs, and templates.

In this chapter, we will start by learning about the types of databases and a few basic database operations using SQL. After that, we will move on to the concept of models and migrations in Django, which assist in faster development by providing a layer of abstraction to facilitate database operations using Python objects.

Databases

A database is a structured collection of data that helps manage information easily. A software layer called the Database Management System (DBMS) is used to store, maintain, and perform operations on the data. Databases are of two types, relational databases and non-relational databases.

Relational Databases

Relational databases or Structured Query Language (SQL) databases store data in a pre-determined structure of rows and columns called tables. A database can be made up of more than one such table, and these tables have a fixed structure of attributes, data types, and relations with other tables. For example, as we just saw in Figure 2.1, the book inventory table has a fixed structure of columns comprising Book Number, Author, Title, and Number of Copies, and the entries form the rows in the table. There could be other tables as well, such as Student Information and Lending Records, which could be related to the inventory table. Also, whenever a book is lent to a student, the records will be stored per the relationships between multiple tables (say, the Student Information and the Book Inventory tables).

This pre-determined structure of rules defining the data types, tabular structures, and relationships across different tables acts like scaffolding or a blueprint for a database. This blueprint is collectively called a database schema. When applied to a database, it will prepare the database to store application data. To manage and maintain these databases, there is a common language for relational databases called SQL. Some examples of relational databases are SQLite, PostgreSQL, MySQL, and OracleDB.

Non-Relational Databases

Non-relational databases or NoSQL (Not Only SQL) databases are designed to store unstructured data. They are well suited to large amounts of generated data that does not follow rigid rules, as is the case with relational databases. Some examples of non-relational databases are Cassandra, MongoDB, CouchDB, and Redis.

For example, imagine that you need to store the stock value of companies in a database using Redis. Here, the company name will be stored as the key and the stock value as the value. Using the key-value type NoSQL database in this use case is appropriate because it stores the desired value for a unique key and is faster to access.

For the scope of this book, we will be dealing only with relational databases as Django does not officially support non-relational databases. However, if you wish to explore, there are many forked projects, such as Django non-rel, that support NoSQL databases.

Database Operations Using SQL

SQL uses a set of commands to perform a variety of database operations, such as creating an entry, reading values, updating an entry, and deleting an entry. These operations are collectively called CRUD operations, which stands for Create, Read, Update, and Delete. To understand database operations in detail, let's first get some hands-on experience with SQL commands. Most relational databases share a similar SQL syntax; however, some operations will differ.

For the scope of this chapter, we will use SQLite as the database. SQLite is a lightweight relational database that is a part of Python standard libraries. That's why Django uses SQLite as its default database configuration. However, we will also learn more about how to perform configuration changes to use other databases in Chapter 17, Deployment of a Django Application (Part 1 – Server Setup). This chapter can be downloaded from the GitHub repository of this book, from http://packt.live/2Kx6FmR.

Data Types in Relational databases

Databases provide us with a way to restrict the type of data that can be stored in a given column. These are called data types. Some examples of data types for a relational database such as SQLite3 are given here:

  • INTEGER is used for storing integers.
  • TEXT can store text.
  • REAL is used for floating-point values.

For example, you would want the title of a book to have TEXT as the data type. So, the database will enforce a rule that no type of data, other than text data, can be stored in that column. Similarly, the book's price can have a REAL data type, and so on.

Exercise 2.01: Creating a Book Database

In this exercise, you will create a book database for a book review application. For better visualization of the data in the SQLite database, you will install an open-source tool called DB Browser for SQLite. This tool helps visualize the data and provides a shell to execute the SQL commands.

If you haven't done so already, visit the URL https://sqlitebrowser.org and from the downloads section, install the application as per your operating system and launch it. Detailed instructions for DB Browser installation can be found in the Preface.

Note

Database operations can be performed using a command-line shell as well.

  1. After launching the application, create a new database by clicking New Database in the top-left corner of the application. Create a database named bookr, as you are working on a book review application:
    Figure 2.2: Creating a database named bookr

    Figure 2.2: Creating a database named bookr

  2. Next, click the Create Table button in the top-left corner and enter book as the table name.

    Note

    After clicking the Save button, you may find that the window for creating a table opens up automatically. In that case, you won't have to click the Create Table button; simply proceed with the creation of the book table as specified in the preceding step.

  3. Now, click the Add field button, enter the field name as title, and select the type as TEXT from the dropdown. Here TEXT is the data type for the title field in the database:
    Figure 2.3: Adding a TEXT field named title

    Figure 2.3: Adding a TEXT field named title

  4. Similarly, add two more fields for the table named publisher and author and select TEXT as the type for both the fields. Then, click the OK button:
    Figure 2.4: Creating TEXT fields named publisher and author

Figure 2.4: Creating TEXT fields named publisher and author

This creates a database table called book in the bookr database with the fields title, publisher, and author. This can be seen as follows:

Figure 2.5: Database with the fields title, publisher, and author

Figure 2.5: Database with the fields title, publisher, and author

In this exercise, we used an open-source tool called DB Browser (SQLite) to create our first database called bookr, and in it, we created our first table named book.

SQL CRUD Operations

Let's assume that the editors or the users of our book review application want to make some modifications to the book inventory, such as adding a few books to the database, updating an entry in the database, and so on. SQL provides various ways to perform such CRUD operations. Before we dive into the world of Django models and migrations, let's explore these basic SQL operations first.

For the CRUD operations that follow, you will be running a few SQL queries. To run them, navigate to the Execute SQL tab in DB Browser. You can type in or paste the SQL queries we've listed in the sections that follow in the SQL 1 window. You can spend some time modifying your queries, and understanding them, before you execute them. When you're ready, click the icon that looks like a Play button or press the F5 key to execute the command. The results will show up in the window below the SQL 1 window:

Figure 2.6: Executing SQL queries in DB Browser

Figure 2.6: Executing SQL queries in DB Browser

SQL Create Operations

The Create operation in SQL is performed using the insert command, which, as the name implies, lets us insert data into the database. Let's go back to our bookr example. Since we have already created the database and the book table, we can now create or insert an entry in the database by executing the following command:

insert into book values ('The Sparrow Warrior', 'Super Hero   Publications', 'Patric Javagal');

This inserts into the table named book the values defined in the command. Here, The Sparrow Warrior is the title, Super Hero Publications is the publisher, and Patric Javagal is the author of the book. Note that the order of insertion corresponds with the way we have created our table; that is, the values are inserted into the columns representing title, publisher, and author respectively. Similarly, let's execute two more inserts to populate the book table:

insert into book values ('Ninja Warrior', 'East Hill Publications',   'Edward Smith');
insert into book values ('The European History', 'Northside   Publications', 'Eric Robbins');

The three inserts executed so far will insert three rows into the book table. But how do we verify that? How would we know whether those three entries we inserted were entered into the database correctly? Let's learn how to do that in the next section.

SQL Read Operations

We can read from the database using the select SQL operation. For example, the following SQL select command retrieves the selected entries created in the book table:

select title, publisher, author from book;

You should see the following output:

Figure 2.7: Output after using the select command

Figure 2.7: Output after using the select command

Here, select is the command that reads from the database, and the fields title, publisher, and author are the columns that we intend to select from the book table. Since these are all the columns the database has, the select statement has returned all the values present in the database. The select statement is also called a SQL query. An alternate way to get all the fields in the database is by using the wildcard * in the select query instead of specifying all the column names explicitly:

select * from book;

This will return the same output as shown in the preceding figure. Now, suppose we want to get the author name for the book titled The Sparrow Warrior; in this case, the select query would be as follows:

select author from book where title="The Sparrow Warrior";

Here, we have added a special SQL keyword called where so that the select query returns only the entries that match the condition. The result of the query, of course, will be Patric Javagal. Now, what if we wanted to change the name of the book's publisher?

SQL Update Operations

In SQL, the way to update a record in the database is by using the update command:

update book set publisher = 'Northside Publications' where   title='The Sparrow Warrior';

Here, we are setting the value of publisher to Northside Publications if the value of the title is The Sparrow Warrior. We can then run the select query we ran in the SQL Read Operations section to see how the updated table looks after running the update command:

Figure 2.8: Updating the value of publisher for the title The Sparrow Warrior

Figure 2.8: Updating the value of publisher for the title The Sparrow Warrior

Next, what if we wanted to delete the title of the record we just updated?

SQL Delete Operations

Here is an example of how to delete a record from the database using the delete command:

delete from book where title='The Sparrow Warrior';

delete is the SQL keyword for delete operations. Here, this operation will be performed only if the title is The Sparrow Warrior. Here is how the book table will look after the delete operation:

Figure 2.9: Output after performing the delete operation

Figure 2.9: Output after performing the delete operation

These are the basic operations of SQL. We will not go very deep into all the SQL commands and syntax, but feel free to explore more about database base operations using SQL.

Note

For further reading, you can start by exploring some advanced SQL select operations with join statements, which are used to query data across multiple tables. For a detailed course on SQL, you can refer to The SQL Workshop (https://www.packtpub.com/product/the-sql-workshop/9781838642358).

Django ORM

Web applications constantly interact with databases, and one of the ways to do so is using SQL. If you decide to write a web application without a web framework like Django and instead use Python alone, Python libraries such as psycopg2 could be used to interact directly with the databases using SQL commands. But while developing a web application with multiple tables and fields, SQL commands can easily become overly complex and thus difficult to maintain. For this reason, popular web frameworks such as Django provide a level of abstraction using which we can easily work with databases. The part of Django that helps us do this is called ORM, which stands for Object Relational Mapping.

Django ORM converts object-oriented Python code into actual database constructs such as database tables with data type definitions and facilitates all the database operations via simple Python code. Because of this, we do not have to deal with SQL commands while performing database operations. This helps in faster application development and ease in maintaining the application source code.

Django supports relational databases such as SQLite, PostgreSQL, Oracle Database, and MySQL. Django's database abstraction layer ensures that the same Python/Django source code can be used across any of the above relational databases with very little modification to the project settings. Since SQLite is part of the Python libraries and Django is configured by default to SQLite, for the scope of this chapter, we shall use SQLite while we learn about Django models and migrations.

Database Configuration and Creating Django Applications

As we have already seen in Chapter 1, Introduction to Django, when we create a Django project and run the Django server, the default database configuration is of SQLite3. The database configuration will be present in the project directory, in the settings.py file.

Note

Make sure you go through the settings.py file for the bookr app. Going through the entire file once will help you understand the concepts that follow. You can find the file at this link: http://packt.live/2KEdaUM.

So, for our example project, the database configuration will be present at the following location: bookr/settings.py. The default database configuration present in this file, when a Django project is created, is as follows:

DATABASES = {\
             'default': {\
                         'ENGINE': 'django.db.backends.sqlite3',\
                         'NAME': os.path.join\
                                 (BASE_DIR, 'db.sqlite3'),}}

Note

The preceding code snippet uses a backslash ( \ ) to split the logic across multiple lines. When the code is executed, Python will ignore the backslash, and treat the code on the next line as a direct continuation of the current line.

The DATABASES variable is assigned with a dictionary containing the database details for the project. Inside the dictionary, there is a nested dictionary with a key as default. This holds the configuration of a default database for the Django project. The reason we have a nested dictionary with default as a key is that a Django project could potentially interact with multiple databases, and the default database is the one used by Django for all operations unless explicitly specified. The ENGINE key represents which database engine is being used; in this case, it is sqlite3.

The NAME key defines the name of the database, which can have any value. But for SQLite3, since the database is created as a file, NAME can have the full path of the directory where the file needs to be created. The full path of the db file is processed by joining (or concatenating) the previously defined path in BASE_DIR with db.sqlite3. Note that BASE_DIR is the project directory as already defined in the settings.py file.

If you are using other databases, such as PostgreSQL, MySQL, and so on, changes will have to be made in the preceding database settings as shown here:

DATABASES = {\
             'default': {\
                         'ENGINE': 'django.db\
                                    .backends.postgresql',\
                         'NAME': 'bookr',\
                         'USER': <username>,\
                         'PASSWORD': <password>,\
                         'HOST': <host-IP-address>,\
                         'PORT': '5432',}}

Here, changes have been made to ENGINE to use PostgreSQL. The host IP address and port number of the server need to be provided for HOST and PORT respectively. As the names suggest, USER is the database username and PASSWORD is the database password. In addition to changes in the configuration, we will have to install the database drivers or bindings along with the database host and credentials. This will be covered in detail in later chapters, but for now, since we are using SQLite3, the default configuration will be sufficient. Note that the above is just an example to show the changes you'll need to make to use a different database such as PostgreSQL, but since we are using SQLite, we shall use the database configuration that exists already, and there is no need to make any modifications to the database settings.

Django Apps

A Django project can have multiple apps that often act as discrete entities. That's why, whenever required, an app can be plugged into a different Django project as well. For example, if we are developing an e-commerce web application, the web application can have multiple apps, such as a chatbot for customer support or a payment gateway to accept payments as users purchase goods from the application. These apps, if needed, can also be plugged into or reused in a different project.

Django comes with the following apps enabled by default. The following is a snippet from a project's settings.py file:

INSTALLED_APPS = ['django.contrib.admin',\
                  'django.contrib.auth',\
                  'django.contrib.contenttypes',\
                  'django.contrib.sessions',\
                  'django.contrib.messages',\
                  'django.contrib.staticfiles',]

These are a set of installed or default apps used for the admin site, authentication, content types, sessions, messaging, and an application to collect and manage static files. In the upcoming chapters, we shall study this in-depth. For the scope of this chapter, though, we shall understand why Django migration is needed for these installed apps.

Django Migration

As we have learned before, Django's ORM helps make database operations simpler. A major part of the operation is to transform the Python code into database structures such as database fields with stated data types and tables. In other words, the transformation of Python code into database structures is known as migration. Instead of creating dozens of tables by running SQL queries, you would write models for them in Python, something you'll learn to do in an upcoming section titled Creating Models and Migrations. These models will have fields, which form the blueprints of database tables. The fields, in turn, will have different field types giving us more information about the type of data stored there (recall how we specified the data type of our field as TEXT in step 4 of Exercise 2.01, Creating a Book Database).

Since we have a Django project set up, let's perform our first migration. Although we have not added any code yet to our project, we can migrate the applications listed in INSTALLED_APPS. This is necessary because Django's installed apps need to store the relevant data in the database for their operations, and migration will create the required database tables to store the data in the database. The following command should be entered in the terminal or shell to do this:

python manage.py migrate

Note

For macOS, you can use python3 instead of python in the preceding command.

Here, manage.py is a script that was automatically created when the project was created. It is used for carrying out managerial or administrative tasks. By executing this command, we create all the database structures required by the installed apps.

As we are using DB Browser for SQLite to browse the database, let's take a look at the database for which changes have been made after executing the migrate command.

The database file will have been created in the project directory under the name db.sqlite3. Open DB Browser, click Open Database, navigate until you find the db.sqlite3 file, and open it. You should see a set of newly created tables created by the Django migration. It will look as follows in DB Browser:

Figure 2.10: Contents of the db.sqlite3 file

Figure 2.10: Contents of the db.sqlite3 file

Now, if we browse through the newly created database structure by clicking the database tables, we see the following:

Figure 2.11: Browsing through the newly created database structure

Figure 2.11: Browsing through the newly created database structure

Notice that the database tables created have different fields, each with their respective data types. Click the Browse data tab in DB Browser and select a table from the dropdown. For instance, after clicking the auth_group_permissions table, you should see something like this:

Figure 2.12: Viewing the auth_group_permissions table

Figure 2.12: Viewing the auth_group_permissions table

You will see that there is no data available for these tables yet because Django migration only creates the database structure or the blueprint, and the actual data in the database is stored during the operation of the application. Now since we have migrated the built-in or default Django apps, let's try to create an app and perform a Django migration.

Creating Django Models and Migrations

A Django model is essentially a Python class that holds the blueprint for creating a table in a database. The models.py file can have many such models, and each model transforms into a database table. The attributes of the class form the fields and relationships of the database table as per the model definitions.

For our reviews application, we need to create the following models and their database tables consequently:

  • Book: This should store information about books.
  • Contributor: This should store information about the person(s) who contributed to writing the book, such as author, co-author, or editor.
  • Publisher: As the name implies, this refers to the book publisher.
  • Review: This should store all the books' reviews written by the users of the application.

Every book in our application will need to have a publisher, so let's create Publisher as our first model. Enter the following code in reviews/models.py:

from django.db import models
class Publisher(models.Model):
    """A company that publishes books."""
    name = models.CharField\
           (max_length=50, \
            help_text="The name of the Publisher.")
    website = models.URLField\
              (help_text="The Publisher's website.")
    email = models.EmailField\
            (help_text="The Publisher's email address.")

Note

You can take a look at the complete models.py file for the bookr app by clicking the following link: http://packt.live/3hmFQxn.

The first line of code imports the Django's models module. While this line will be autogenerated at the time of the creation of the Django app, do make sure you add it if it is not present. Following the import, the rest of the code is defining a class named Publisher, which will be a subclass of Django's models.Model. Furthermore, this class will have attributes or fields such as name, website, and email.

Field Types

As we can see, each of these fields is defined to have the following types:

  • CharField: This field type is used to store shorter string fields, for example, Packt Publishing. For very large strings, we use TextField.
  • EmailField: This is similar to CharField, but validates whether the string represents a valid email address, for example, customersupport@packtpub.com.
  • URLField: This is again similar to CharField, but validates whether the string represents a valid URL, for example, https://www.packtpub.com.

Field Options

Django provides a way to define field options to a model's field. These field options are used to set a value or a constraint, and so on. For example, we can set a default value for a field using default=<value>, to ensure that every time a record is created in the database for the field, it is set to a default value specified by us. Following are the two field options that we have used while defining the Publisher model:

  • help_text: This is a field option that helps us add descriptive text for a field that gets automatically included for Django forms.
  • max_length: This option is provided to CharField where it defines the maximum length of the field in terms of the number of characters.

Django has many more field types and field options that can be explored from the extensive official Django documentation. As we go about developing our sample book review application, we shall learn about those types and fields that are used for the project. Now let's migrate the Django models into the database. Execute the following command in the shell or terminal to do that (run it from the folder where your manage.py file is stored):

python manage.py makemigrations reviews

The output of the command looks like this:

Migrations for 'reviews':
  reviews/migrations/0001_initial.py
    - Create model Publisher

The makemigrations <appname> command creates the migration scripts for the given app; in this case, for the reviews app. Notice that after running makemigrations, there is a new file created under the migrations folder:

Figure 2.13: New file under the migrations folder

Figure 2.13: New file under the migrations folder

This is the migration script created by Django. When we run makemigrations without the app name, the migration scripts will be created for all the apps in the project. Next, let's list the project migration status. Remember that earlier, we applied migrations to Django's installed apps and now we have created a new app, reviews. The following command, when run in the shell or terminal, will show the status of model migrations throughout the project (run it from the folder where your manage.py file is stored):

python manage.py showmigrations

The output for the preceding command is as follows:

admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
reviews
 [ ] 0001_initial
sessions
 [X] 0001_initial

Here, the [X] mark indicates that the migrations have been applied. Notice the difference that all the other apps' migrations have applied except that of reviews. The showmigrations command can be executed to understand the migration status, but this is not a mandatory step while performing model migrations.

Next, let's understand how Django transforms a model into an actual database table. This can be understood by running the sqlmigrate command:

python manage.py sqlmigrate reviews 0001_initial 

We should see the following output:

BEGIN;
--
-- Create model Publisher
--
CREATE TABLE "reviews_publisher" ("id" integer \
    NOT NULL PRIMARY KEY AUTOINCREMENT, "name" \
    varchar(50) NOT NULL, "website" varchar(200) \
    NOT NULL, "email" varchar(254) NOT NULL);
COMMIT;

The preceding snippet shows the SQL command equivalent used when Django migrates the database. In this case, we are creating the reviews_publisher table with the fields name, website, and email with the defined field types. Furthermore, all these fields are defined to be NOT NULL, implying that the entries for these fields cannot be null and should have some value. The sqlmigrate command is not a mandatory step while doing the model migrations.

Primary Keys

Let's assume that a database table called users, as its name suggests, stores information about users. Let's say it has more than 1,000 records and there are at least 3 users with the same name, Joe Burns. How do we uniquely identify these users from the application? The solution is to have a way to uniquely identify each record in the database. This is done using Primary Keys. A primary key is unique for a database table, and as a rule, a table cannot have two rows with the same primary key. In Django, when the primary key is not explicitly mentioned in the database models, Django automatically creates id as the primary key (of type integer), which auto increments as new records are created.

In the previous section, notice the output of the python manage.py sqlmigrate command. While creating the Publisher table, the SQL CREATE TABLE command was adding one more field called id to the table. id is defined to be PRIMARY KEY AUTOINCREMENT. In relational databases, a primary key is used to uniquely identify an entry in the database. For example, the book table has id as the primary key, which has numbers starting from 1. This value increments by 1 as new records are created. The integer value of id is always unique across the book table. Since the migration script has already been created by executing makemigrations, let's now migrate the newly created model in the reviews app by executing the following command:

python manage.py migrate reviews

You should get the following output:

Operations to perform:
    Apply all migrations: reviews
Running migrations:
    Applying reviews.0001_initial... OK

This operation creates the database table for the reviews app. The following is a snippet from DB Browser indicating the new table reviews_publisher has been created in the database:

Figure 2.14: reviews_publisher table created after executing the migration command

Figure 2.14: reviews_publisher table created after executing the migration command

So far, we have explored how to create a model and migrate it into the database. Let's now work on creating the rest of the models for our book review application. As we've already seen, the application will have the following database tables:

  • Book: This is the database table that holds the information about the book itself. We have already created a Book model and have migrated this to the database.
  • Publisher: This table holds information about the book publisher.
  • Contributor: This table holds information about the contributor, that is, the author, co-author, or editor.
  • Review: This table holds information about the review comments posted by the reviewers.

Let's add the Book and Contributor models, as shown in the following code snippet, into reviews/models.py:

class Book(models.Model):
    """A published book."""
    title = models.CharField\
            (max_length=70, \
             help_text="The title of the book.")
    publication_date = models.DateField\
                       (verbose_name=\
                        "Date the book was published.")
    isbn = models.CharField\
           (max_length=20, \
            verbose_name="ISBN number of the book.")
class Contributor(models.Model):
"""
A contributor to a Book, e.g. author, editor, \
co-author.
"""
  first_names = models.CharField\
                (max_length=50, \
                 help_text=\
                 "The contributor's first name or names.")
    last_names = models.CharField\
                 (max_length=50, \
                  help_text=\
                  "The contributor's last name or names.")
    email = models.EmailField\
            (help_text="The contact email for the contributor.")

The code is self-explanatory. The Book model has the fields title, publication_date, and isbn. The Contributor model has the fields first_names and last_names fields and the email ID of the contributor. There are some newly added models as well, apart from the ones we have seen in the Publisher model. They have DateField as a new field type, which, as the name suggests, is used to store a date. A new field option called verbose_name is also used. It provides a descriptive name for the field.

Relationships

One of the powers of relational databases is the ability to establish relationships between data stored across database tables. Relationships help maintain data integrity by establishing the correct references across tables, which in turn helps maintain the database. Relationship rules, on the other hand, ensure data consistency and prevent duplicates.

In a relational database, there can be the following types of relations:

  • Many to one
  • Many to many
  • One to one

Let's explore each relationship in detail.

Many to One

In this relationship, many records (rows/entries) from one table can refer to one record (row/entry) in another table. For example, there can be many books produced by one publisher. This is a case of a many-to-one relationship. To establish this relationship, we need to use the database's foreign keys. A foreign key in a relational database establishes the relationship between a field from one table and a primary key from a different table.

For example, say you have data about employees belonging to different departments stored in a table called employee_info with their employee ID as the primary key alongside a column that stores their department name; this table also contains a column that stores that department's department ID. Now, there's another table called departments_info, which has department ID as the primary key. In this case, then, the department ID is a foreign key in the employee_info table.

In our bookr app, the Book model can have a foreign key referring to the primary key of the Publisher table. Since we have already created the models for Book, Contributor, and Publisher, now let's establish a many-to-one relationship across the Book and Publisher models. For the Book model, add the last line:

class Book(models.Model):
    """A published book."""
    title = models.CharField\
            (max_length=70, \
             help_text="The title of the book.")
    publication_date = models.DateField\
                       (verbose_name=\
                        "Date the book was published.")
    isbn = models.CharField\
           (max_length=20, \
            verbose_name="ISBN number of the book.")
    publisher = models.ForeignKey\
                (Publisher, on_delete=models.CASCADE)

Now the newly added publisher field is establishing a many-to-one relationship between Book and Publisher using a foreign key. This relationship ensures the nature of a many-to-one relationship, which is that many books can have one publisher:

  • models.ForeignKey: This is the field option to establish a many-to-one relationship.
  • Publisher: When we establish relationships with different tables in Django, we refer to the model that creates the table; in this case, the Publisher table is created by the Publisher model (or the Python class Publisher).
  • on_delete: This is a field option that determines the action to be taken upon the deletion of the referenced object. In this case, the on_delete option is set to CASCADE(models.CASCADE), which deletes the referenced objects.

For example, assume a publisher has published a set of books. For some reason, if the publisher has to be deleted from the application, the next action is CASCADE, which means delete all the referenced books from the application. There are many more on_delete actions, such as the following:

  • PROTECT: This prevents the deletion of the record unless all the referenced objects are deleted.
  • SET_NULL: This sets a null value if the database field has been previously configured to store null values.
  • SET_DEFAULT: Sets to a default value on the deletion of the referenced object.

For our book review application, we will be using only the CASCADE option.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Understand Django functionality and the Model-View-Template (MVT) paradigm
  • Create and iteratively build a book review website, adding features as you build your knowledge
  • Explore advanced concepts such as REST API implementation and third-party module integration

Description

Do you want to develop reliable and secure applications which stand out from the crowd, rather than spending hours on boilerplate code? Then the Django framework is where you should begin. Often referred to as a 'batteries included' web development framework, Django comes with all the core features needed to build a standalone application. Web Development with Django takes this philosophy and equips you with the knowledge and confidence to build real-world applications using Python. Starting with the essential concepts of Django, you'll cover its major features by building a website called Bookr – a repository for book reviews. This end-to-end case study is split into a series of bitesize projects that are presented as exercises and activities, allowing you to challenge yourself in an enjoyable and attainable way. As you progress, you'll learn various practical skills, including how to serve static files to add CSS, JavaScript, and images to your application, how to implement forms to accept user input, and how to manage sessions to ensure a reliable user experience. Throughout this book, you'll cover key daily tasks that are part of the development cycle of a real-world web application. By the end of this book, you'll have the skills and confidence to creatively tackle your own ambitious projects with Django.

Who is this book for?

Web Development with Django is designed for programmers who want to gain web development skills with the Django framework. To fully understand the concepts explained in this book, you must have basic knowledge of Python programming, as well as familiarity with JavaScript, HTML, and CSS.

What you will learn

  • Create a new application and add models to describe your data
  • Use views and templates to control behavior and appearance
  • Implement access control through authentication and permissions
  • Develop practical web forms to add features such as file uploads
  • Develop a RESTful API and JavaScript code that communicates with it
  • Connect to a database such as PostgreSQL
Estimated delivery fee Deliver to Turkey

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$34.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Feb 25, 2021
Length: 826 pages
Edition : 1st
Language : English
ISBN-13 : 9781839212505
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Turkey

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$34.95
(Includes tracking information)

Product Details

Publication date : Feb 25, 2021
Length: 826 pages
Edition : 1st
Language : English
ISBN-13 : 9781839212505
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 171.97
Web Development with Django
$69.99
Learn Python Programming, 3rd edition
$46.99
Django 3 By Example
$54.99
Total $ 171.97 Stars icon

Table of Contents

16 Chapters
1. Introduction to Django Chevron down icon Chevron up icon
2. Models and Migrations Chevron down icon Chevron up icon
3. URL Mapping, Views, and Templates Chevron down icon Chevron up icon
4. Introduction to Django Admin Chevron down icon Chevron up icon
5. Serving Static Files Chevron down icon Chevron up icon
6. Forms Chevron down icon Chevron up icon
7. Advanced Form Validation and Model Forms Chevron down icon Chevron up icon
8. Media Serving and File Uploads Chevron down icon Chevron up icon
9. Sessions and Authentication Chevron down icon Chevron up icon
10. Advanced Django Admin and Customizations Chevron down icon Chevron up icon
11. Advanced Templating and Class-Based Views Chevron down icon Chevron up icon
12. Building a REST API Chevron down icon Chevron up icon
13. Generating CSV, PDF, and Other Binary Files Chevron down icon Chevron up icon
14. Testing Chevron down icon Chevron up icon
15. Django Third-Party Libraries Chevron down icon Chevron up icon
16. Using a Frontend JavaScript Library with Django Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4
(36 Ratings)
5 star 66.7%
4 star 19.4%
3 star 5.6%
2 star 8.3%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Cris LaFortune Apr 12, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
A beginner-friendly introduction to Django. The book walks you through creating databases in Django from start to finish.
Amazon Verified review Amazon
Jonathan Reeves Jun 23, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you are looking to build applications with Python and Django look no further than this book. It is a one stop shop for learning the best practices that are current and modern for developing Django based web apps. I was looking for something that would help me take my Django building skills into 2021 and this book did that. It breaks down the concepts very easily and covers a lot of topics. I highly recommend the title if you are a Python developer looking to build web apps.
Amazon Verified review Amazon
marco pineda May 24, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great book for any Django newcomer looking for a deep dive
Amazon Verified review Amazon
Manish Kumar Jul 24, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This might be the best book written about Django for beginners. It builds a simple web application called "Bookr" for displaying book reviews. And the nice thing about this book is that it gradually introduces new concepts as the web app is fleshed out. It gives you just the right amount of detail for each topic and never bogs you down with unnecessary and obscure knowledge. Highly recommended.
Amazon Verified review Amazon
Sujit Packiaraj Oct 28, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book is easy to read and understand which is rare for a thick programming book. The authors go through each step of building an example web app in high detail. I found Chapter 8 (Media Serving and File Upload), Chapter 12 (REST API's and Token-Based Authentication), and Chapter 14 (Testing) to be especially helpful, containing information I can't easily find online. Overall, I'm glad to have this book as a reference.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela