Web Development with Django - Ben Shaw - E-Book

Web Development with Django E-Book

Ben Shaw

0,0
35,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

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.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 864

Veröffentlichungsjahr: 2021

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Web Development with Django

Learn to build modern web applications with a Python-based framework

Ben Shaw, Saurabh Badhwar, Andrew Bird, Bharath Chandra K S, and Chris Guest

Web Development with Django

Copyright © 2021 Packt Publishing

All rights reserved. No part of this course may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this course to ensure the accuracy of the information presented. However, the information contained in this course is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this course.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this course by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Authors: Ben Shaw, Saurabh Badhwar, Andrew Bird, Bharath Chandra K S, and Chris Guest

Reviewers: Bidhan Mondal and Subhash Sundaravadivelu

Managing Editors: Abhishek Rane and Saumya Jha

Acquisitions Editors: Sneha Shinde, Anindya Sil, and Alicia Wooding

Production Editor: Shantanu Zagade

Editorial Board: Megan Carlisle, Samuel Christa, Mahesh Dhyani, Heather Gopsill, Manasa Kumar, Alex Mazonowicz, Monesh Mirpuri, Bridget Neale, Dominic Pereira, Shiny Poojary, Abhishek Rane, Brendan Rodrigues, Erol Staveley, Ankita Thakur, Nitesh Thakur, and Jonathan Wray

First published: February 2021

Production reference: 2250521

ISBN: 978-1-83921-250-5

Published by Packt Publishing Ltd.

Livery Place, 35 Livery Street

Birmingham B3 2PB, UK

Table of Contents

Preface

1. Introduction to Django

Introduction

Scaffolding a Django Project and App

Exercise 1.01: Creating a Project and App, and Starting the Dev Server

Model View Template

Models

Views

Templates

MVT in Practice

Introduction to HTTP

Processing a Request

Django Project

The myproject Directory

Django Development Server

Django Apps

PyCharm Setup

Exercise 1.02: Project Setup in PyCharm

View Details

URL Mapping Detail

Exercise 1.03: Writing a View and Mapping a URL to It

GET, POST, and QueryDict Objects

Exercise 1.04: Exploring GET Values and QueryDict

Exploring Django Settings

Using Settings in Your Code

Finding HTML Templates in App Directories

Exercise 1.05: Creating a Templates Directory and a Base Template

Rendering a Template with the render Function

Exercise 1.06: Rendering a Template in a View

Rendering Variables in Templates

Exercise 1.07: Using Variables in Templates

Debugging and Dealing with Errors

Exceptions

Exercise 1.08: Generating and Viewing Exceptions

Debugging

Exercise 1.09: Debugging Your Code

Activity 1.01: Creating a Site Welcome Screen

Activity 1.02: Book Search Scaffold

Summary

2. Models and Migrations

Introduction

Databases

Relational Databases

Non-Relational Databases

Database Operations Using SQL

Data Types in Relational databases

Exercise 2.01: Creating a Book Database

SQL CRUD Operations

SQL Create Operations

SQL Read Operations

SQL Update Operations

SQL Delete Operations

Django ORM

Database Configuration and Creating Django Applications

Django Apps

Django Migration

Creating Django Models and Migrations

Field Types

Field Options

Primary Keys

Relationships

Many to One

Many to Many

One-to-One Relationships

Adding the Review Model

Model Methods

Migrating the Reviews App

Django's Database CRUD Operations

Exercise 2.02: Creating an Entry in the Bookr Database

Exercise 2.03: Using the create() Method to Create an Entry

Creating an Object with a Foreign Key

Exercise 2.04: Creating Records for a Many-to-One Relationship

Exercise 2.05: Creating Records with Many-to-Many Relationships

Exercise 2.06: A Many-to-Many Relationship Using the add() Method

Using create() and set() Methods for Many-to-Many Relationships

Read Operations

Exercise 2.07: Using the get() Method to Retrieve an Object

Returning an Object Using the get() Method

Exercise 2.08: Using the all() Method to Retrieve a Set of Objects

Retrieving Objects by Filtering

Exercise 2.09: Using the filter() Method to Retrieve Objects

Filtering by Field Lookups

Using Pattern Matching for Filtering Operations

Retrieving Objects by Excluding

Retrieving Objects Using the order_by() Method

Querying Across Relationships

Querying Using Foreign Keys

Querying Using Model Name

Querying Across Foreign Key Relationships Using the Object Instance

Exercise 2.10: Querying Across a Many-to-Many Relationship Using Field Lookup

Exercise 2.11: A Many-to-Many Query Using Objects

Exercise 2.12: A Many-to-Many Query Using the set() Method

Exercise 2.13: Using the update() Method

Exercise 2.14: Using the delete() Method

Activity 2.01: Create Models for a Project Management Application

Populating the Bookr Project's Database

Summary

3. URL Mapping, Views, and Templates

Introduction

Function-Based Views

Class-Based Views

URL Configuration

Exercise 3.01: Implementing a Simple Function-Based View

Templates

Exercise 3.02: Using Templates to Display a Greeting Message

Django Template Language

Template Variables

Template Tags

Comments

Filters

Exercise 3.03: Displaying a List of Books and Reviews

Template Inheritance

Template Styling with Bootstrap

Exercise 3.04: Adding Template Inheritance and a Bootstrap Navigation Bar

Activity 3.01: Implement the Book Details View

Summary

4. Introduction to Django Admin

Introduction

Creating a Superuser Account

Exercise 4.01: Creating a Superuser Account

CRUD Operations Using the Django Admin App

Create

Retrieve

Update

Delete

Users and Groups

Exercise 4.02: Adding and Modifying Users and Groups through the Admin app

Registering the Reviews Model

Change Lists

The Publisher Change Page

The Book Change Page

Exercise 4.03: Foreign Keys and Deletion Behavior in the Admin App

Customizing the Admin Interface

Site-Wide Django Admin Customizations

Examining the AdminSite object from the Python Shell

Subclassing AdminSite

Activity 4.01: Customizing the SiteAdmin

Customizing the ModelAdmin Classes

The List Display Fields

The Filter

Exercise 4.04: Adding a Date list_filter and date_hierarchy

The Search Bar

Excluding and Grouping Fields

Activity 4.02: Customizing the Model Admins

Summary

5. Serving Static Files

Introduction

Static File Serving

Introduction to Static File Finders

Static File Finders: Use During a Request

AppDirectoriesFinder

Static File Namespacing

Exercise 5.01: Serving a File from an App Directory

Generating Static URLs with the static Template Tag

Exercise 5.02: Using the static Template Tag

FileSystemFinder

Exercise 5.03: Serving from a Project static Directory

Static File Finders: Use During collectstatic

Exercise 5.04: Collecting Static Files for Production

STATICFILES_DIRS Prefixed Mode

The findstatic Command

Exercise 5.05: Finding Files Using findstatic

Serving the Latest Files (for Cache Invalidation)

Exercise 5.06: Exploring the ManifestFilesStorage Storage Engine

Custom Storage Engines

Activity 5.01: Adding a reviews Logo

Activity 5.02: CSS Enhancements

Activity 5.03: Adding a Global Logo

Summary

6. Forms

Introduction

What Is a Form?

The <form> Element

Types of Inputs

Exercise 6.01: Building a Form in HTML

Form Security with Cross-Site Request Forgery Protection

Accessing Data in the View

Exercise 6.02: Working with POST Data in a View

Choosing between GET and POST

Why Use GET When We Can Put Parameters in the URL?

The Django Forms Library

Defining a Form

Rendering a Form in a Template

Exercise 6.03: Building and Rendering a Django Form

Validating Forms and Retrieving Python Values

Exercise 6.04: Validating Forms in a View

Built-In Field Validation

Exercise 6.05: Adding Extra Field Validation

Activity 6.01: Book Searching

Summary

7. Advanced Form Validation and Model Forms

Introduction

Custom Field Validation and Cleaning

Custom Validators

Cleaning Methods

Multi-Field Validation

Exercise 7.01: Custom Clean and Validation Methods

Placeholders and Initial Values

Exercise 7.02: Placeholders and Initial Values

Creating or Editing Django Models

The ModelForm Class

Exercise 7.03: Creating and Editing a Publisher

Activity 7.01: Styling and Integrating the Publisher Form

Activity 7.02: Review Creation UI

Summary

8. Media Serving and File Uploads

Introduction

Settings for Media Uploads and Serving

Serving Media Files in Development

Exercise 8.01: Configuring Media Storage and Serving Media Files

Context Processors and Using MEDIA_URL in Templates

Exercise 8.02: Template Settings and Using MEDIA_URL in Templates

File Uploads Using HTML Forms

Working with Uploaded Files in a View

Security and Trust of Browsers' Sent Values

Exercise 8.03: File Upload and Download

File Uploads with Django Forms

Exercise 8.04: File Uploads with a Django Form

Image Uploads with Django Forms

Resizing an Image with Pillow

Exercise 8.05: Image Uploads using Django Forms

Serving Uploaded (and Other) Files Using Django

Storing Files on Model Instances

Storing Images on Model Instances

Working with FieldFile

Custom Storage Engines

Reading a Stored FieldFile

Storing Existing Files or Content in FileField

Writing PIL Images to ImageField

Referring to Media in Templates

Exercise 8.06: FileField and ImageField on Models

ModelForms and File Uploads

Exercise 8.07: File and Image Uploads Using a ModelForm

Activity 8.01: Image and PDF Uploads of Books

Activity 8.02: Displaying Cover and Sample Links

Summary

9. Sessions and Authentication

Introduction

Middleware

Middleware Modules

Implementing Authentication Views and Templates

Exercise 9.01: Repurposing the Admin App Login Template

Password Storage in Django

The Profile Page and the request.user Object

Exercise 9.02: Adding a Profile Page

Authentication Decorators and Redirection

Exercise 9.03: Adding Authentication Decorators to the Views

Enhancing Templates with Authentication Data

Exercise 9.04: Toggling Login and Logout Links in the Base Template

Activity 9.01: Authentication-Based Content Using Conditional Blocks in Templates

Sessions

The Session Engine

Do You Need to Flag Cookie Content?

Pickle or JSON storage

Exercise 9.05: Examining the Session Key

Storing Data in Sessions

Exercise 9.06: Storing Recently Viewed Books in Sessions

Activity 9.02: Using Session Storage for the Book Search Page

Summary

10. Advanced Django Admin and Customizations

Introduction

Customizing the Admin Site

Discovering Admin Files in Django

Django's AdminSite Class

Exercise 10.01: Creating a Custom Admin Site for Bookr

Overriding the Default admin.site

Exercise 10.02: Overriding the Default Admin Site

Customizing Admin Site Text Using AdminSite Attributes

Customizing Admin Site Templates

Exercise 10.03: Customizing the Logout Template for the Bookr Admin Site

Adding Views to the Admin Site

Creating the View Function

Accessing Common Template Variables

Mapping URLs for the Custom View

Restricting Custom Views to the Admin Site

Exercise 10.04: Adding Custom Views to the Admin Site

Passing Additional Keys to the Templates Using Template Variables

Activity 10.01: Building a Custom Admin Dashboard with Built-In Search

Summary

11. Advanced Templating and Class-Based Views

Introduction

Template Filters

Custom Template Filters

Template Filters

Setting Up the Directory for Storing Template Filters

Setting Up the Template Library

Implementing the Custom Filter Function

Using Custom Filters inside Templates

Exercise 11.01: Creating a Custom Template Filter

String Filters

Template Tags

Types of Template Tags

Simple Tags

How to Create a Simple Template Tag

Setting Up the Directory

Setting Up the Template Library

Implementing a Simple Template Tag

Using Simple Tags inside Templates

Exercise 11.02: Creating a Custom Simple Tag

Passing the Template Context in a Custom Template Tag

Inclusion Tags

Implementing Inclusion Tags

Using an Inclusion Tag inside a Template

Exercise 11.03: Building a Custom Inclusion Tag

Django Views

Class-Based Views

Exercise 11.04: Creating a Book Catalog Using a CBV

CRUD Operations with CBVs

Create View

Update View

Delete View

Read View

Activity 11.01: Rendering Details on the User Profile Page Using Inclusion Tags

Summary

12. Building a REST API

Introduction

REST APIs

Django REST Framework

Installation and Configuration

Functional API Views

Exercise 12.01: Creating a Simple REST API

Serializers

Exercise 12.02: Creating an API View to Display a List of Books

Class-Based API Views and Generic Views

Model Serializers

Exercise 12.03: Creating Class-Based API Views and Model Serializers

Activity 12.01: Creating an API Endpoint for a Top Contributors Page

ViewSets

Routers

Exercise 12.04: Using ViewSets and Routers

Authentication

Token-Based Authentication

Exercise 12.05: Implementing Token-Based Authentication for Bookr APIs

Summary

13. Generating CSV, PDF, and Other Binary Files

Introduction

Working with CSV Files inside Python

Working with Python's CSV Module

Reading Data from a CSV File

Exercise 13.01: Reading a CSV File with Python

Writing to CSV Files Using Python

Exercise 13.02: Generating a CSV File Using Python's csv Module

A Better Way to Read and Write CSV Files

Working with Excel Files in Python

Binary File Formats for Data Exports

Working with XLSX Files Using the XlsxWriter Package

XLSX Files

The XlsxWriter Python Package

Creating a Workbook

Creating a Worksheet

Writing Data to the Worksheet

Writing the Data to the Workbook

Exercise 13.03: Creating XLSX Files in Python

Working with PDF Files in Python

Converting Web Pages to PDFs

Exercise 13.04: Generating a PDF Version of a Web Page in Python

Playing with Graphs in Python

Generating Graphs with plotly

Setting Up a Figure

Generating a Plot

Rendering a Plot on a Web Page

Exercise 13.05: Generating Graphs in Python

Integrating plotly with Django

Integrating Visualizations with Django

Exercise 13.06: Visualizing a User's Reading History on the User Profile Page

Activity 13.01: Exporting the Books Read by a User as an XLSLX File

Summary

14. Testing

Introduction

The Importance of Testing

Automation Testing

Testing in Django

Implementing Test Cases

Unit Testing in Django

Utilizing Assertions

Exercise 14.01: Writing a Simple Unit Test

Types of Assertions

Performing Pre-Test Setup and Cleanup after Every Test Case Run

Testing Django Models

Exercise 14.02: Testing Django Models

Testing Django Views

Exercise 14.03: Writing Unit Tests for Django Views

Testing Views with Authentication

Exercise 14.04: Writing Test Cases to Validate Authenticated Users

Django Request Factory

Exercise 14.05: Using a Request Factory to Test Views

Testing Class-Based Views

Test Case Classes in Django

SimpleTestCase

TransactionTestCase

LiveServerTestCase

Modularizing Test Code

Activity 14.01: Testing Models and Views in Bookr

Summary

15. Django Third-Party Libraries

Introduction

Environment Variables

django-configurations

manage.py changes

Configuration from Environment Variables

Exercise 15.01: Django Configurations Setup

dj-database-url

Exercise 15.02: dj-database-url and Setup

The Django Debug Toolbar

Exercise 15.03: Setting Up the Django Debug Toolbar

django-crispy-forms

The crispy Filter

The crispy Template Tag

Exercise 15.04: Using Django Crispy Forms with the SearchForm

django-allauth

django-allauth Installation and Setup

GitHub Auth Setup

Google Auth Setup

Initiating Authentication with django-allauth

Other django-allauth Features

Activity 15.01: Using FormHelper to Update Forms

Summary

16. Using a Frontend JavaScript Library with Django

Introduction

JavaScript Frameworks

JavaScript Introduction

React

Components

Exercise 16.01: Setting Up a React Example

JSX

Exercise 16.02: JSX and Babel

JSX Properties

Exercise 16.03: React Component Properties

JavaScript Promises

fetch

The JavaScript map Method

Exercise 16.04: Fetching and Rendering Books

The verbatim Template Tag

Activity 16.01: Reviews Preview

Summary

Preface

1. Introduction to Django

Overview

This chapter introduces you to Django and its role in web development. You will begin by learning how the Model View Template (MVT) paradigm works and how Django processes HTTP requests and responses. Equipped with the basic concepts, you'll create your first Django project, called Bookr, an application for adding, viewing, and managing book reviews. It's an application you'll keep enhancing and adding features to throughout this book. You will then learn about the manage.py command (used to orchestrate Django actions). You will use this command to start the Django development server and test whether the code you've written works as expected. You will also learn how to work with PyCharm, a popular Python IDE that you'll be using throughout this book. You will use it to write code that returns a response to your web browser. Finally, you'll learn how to use PyCharm's debugger to troubleshoot problems with your code. By the end of this chapter, you'll have the necessary skills to start creating projects using Django.

Introduction

"The web framework for perfectionists with deadlines." It's a tagline that aptly describes Django, a framework that has been around for over 10 years now. It is battle-tested and widely used, with more and more people using it every day. All this might make you think that Django is old and no longer relevant. On the contrary, its longevity has proved that its Application Programming Interface (API) is reliable and consistent, and even those who learned Django v1.0 in 2007 can mostly write the same code for Django 3 today. Django is still in active development, with bugfixes and security patches being released monthly.

Like Python, the language in which it is written, Django is easy to learn, yet powerful and flexible enough to grow with your needs. It is a "batteries-included" framework, which is to say that you do not have to find and install many other libraries or components to get your application up and running. Other frameworks, such as Flask or Pylons, require manually installing third-party frameworks for database connections or template rendering. Instead, Django has built-in support for database querying, URL mapping, and template rendering (we'll go into detail on what these mean soon). But just because Django is easy to use doesn't mean it is limited. Django is used by many large sites, including Disqus (https://disqus.com/), Instagram (https://www.instagram.com/), Mozilla (https://www.mozilla.org/), Pinterest (https://www.pinterest.com/), Open Stack (https://www.openstack.org/), and National Geographic (http://www.nationalgeographic.com/).

Where does Django fit into the web? When talking about web frameworks, you might think of frontend JavaScript frameworks such as ReactJS, Angular, or Vue. These frameworks are used to enhance or add interactivity to already-generated web pages. Django sits in the layer beneath these tools and instead is responsible for routing a URL, fetching data from databases, rendering templates, and handling form input from users. However, this does not mean you must pick one or the other; JavaScript frameworks can be used to enhance the output from Django, or to interact with a REST API generated by Django.

In this book, we will build a Django project using the methods that professional Django developers use every day. The application is called Bookr, and it allows browsing and adding books and book reviews. This book is divided into four sections. In the first section, we'll start with the basics of scaffolding a Django app and quickly build some pages and serve them with the Django development server. You'll be able to add data to the database using the Django admin site.

The next section focuses on adding enhancements to Bookr. You'll serve static files to add styles and images to the site. By using Django's form library, you'll add interactivity, and by using file uploads, you will be able to upload book covers and other files. You'll then implement user login and learn how to store information about the current user in the session.

In section three, you'll build on your existing knowledge and move to the next level of development. You'll customize the Django admin site and then learn about advanced templating. Next, you'll learn how to build a REST API and generate non-HTML data (such as CSVs and PDFs), and you'll finish the section by learning about testing Django.

Many third-party libraries are available to add functionality to Django and to make development easier and thus save time. In the final section, you'll learn about some of the useful ones and how to integrate them into your application. Applying this knowledge, you'll integrate a JavaScript library to communicate with the REST framework you built in the previous section. Finally, you'll learn how to deploy your Django application to a virtual server.

By the end of the book, you will have enough experience to design and build your own Django project from start to finish.

Scaffolding a Django Project and App

Before diving deep into the theory behind Django paradigms and HTTP requests, we'll show you how easy it is to get a Django project up and running. After this first section and exercise, you will have created a Django project, made a request to it with your browser, and seen the response.

A Django project is a directory that contains all the data for your project: code, settings, templates, and assets. It is created and scaffolded by running the django-admin.py command on the command line with the startproject argument and providing the project name. For example, to create a Django project with the name myproject, the command that is run is this:

django-admin.py startproject myproject

This will create the myproject directory, which Django populates with the necessary files to run the project. Inside the myproject directory are two files (shown in Figure 1.1):

Figure 1.1: Project directory for myproject

manage.py is a Python script that is executed at the command line to interact with your project. We will use it to start the Django dev server, a development web server you will use to interact with your Django project on your local computer. Like django-admin.py, commands are passed in on the command line. Unlike django-admin.py, this script is not mapped in your system path, so we must execute it using Python. We will need to use the command line to do that. For example, inside the project directory, run the following command:

python3 manage.py runserver

This passes the runserver command to the manage.py script, which starts the Django dev server. We will examine more of the commands that manage.py accepts in the Django Project section. When interacting with manage.py in this way, we call these management commands. For example, we might say that we are "executing the runserver management command."

The startproject command also created a directory with the same name as the project, in this case, myproject (Figure 1.1). This is a Python package that contains settings and some other configuration files that your project needs to run. We will examine its contents in the Django Project section.

After starting the Django project, the next thing to do is to start a Django app. We should try to segregate our Django project into different apps, grouped by functionality. For example, with Bookr, we will have a reviews app. This will hold all the code, HTML, assets, and database classes specific to working with book reviews. If we decided to expand Bookr to sell books as well, we might add a store application, containing the files for the bookstore. Apps are created with the startapp management command, passing in the application name. For example:

python3 manage.py startapp myapp

This creates the app directory (myapp) inside the project directory. Django automatically populates this with files for the app that are ready to be filled in when you start developing. We'll examine these files and discuss what makes a good app in the Django Apps section.

Now that we've introduced the basic commands to scaffold a Django project and application, let's put them into practice by starting the Bookr project in the first exercise of this book.

Exercise 1.01: Creating a Project and App, and Starting the Dev Server

Throughout this book, we will be building a book review website named Bookr. It will allow you to add fields for publishers, contributors, books, and reviews. A publisher will publish one or more books, and each book will have one or more contributors (author, editor, co-author, and so on). Only admin users will be allowed to modify these fields. Once a user has signed up for an account on the site, they will be able to start adding reviews to a book.

In this exercise, you will scaffold the bookr Django project, test that Django is working by running the dev server, then create the reviews Django app.

You should already have a virtual environment set up with Django installed. To learn how to do that, you can refer to the Preface. Once you're ready, let's start by creating the Bookr project:

Open a Terminal and run the following command to create the bookr project directory and the default subfolders:

django-admin startproject bookr

This command does not generate any output but will create a folder called bookr inside the directory in which you ran the command. You can look inside this directory and see the items we described before for the myproject example: the bookr package directory and manage.py file.

We can now test that the project and Django are set up correctly by running the Django dev server. Starting the server is done with the manage.py script.

In your Terminal (or Command Prompt), change into the bookr project directory (using the cd command), then run the manage.py runserver command.

python3 manage.py runserver

Note

On Windows, you may need to run replace python3 (highlighted) with just python to make the command work every time you run it.

This command starts the Django dev server. You should get output similar to the following:

Watching for file changes with StatReloader

Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.

Run 'python manage.py migrate' to apply them.

September 14, 2019 - 09:40:45

Django version 3.0a1, using settings 'bookr.settings'

Starting development server at http://127.0.0.1:8000/

Quit the server with CONTROL-C.

You will probably have some warnings about unapplied migrations, but that's okay for now.

Open up a web browser and go to http://127.0.0.1:8000/, which will show you the Django welcome screen (Figure 1.2). If you see this, you know your Django project was created successfully and it all is working fine for now:

Figure 1.2: Django welcome screen

Go back to your Terminal and stop the development server running using the Ctrl + C key combination.We'll now create the reviews app for the bookr project. In your Terminal, make sure you are in the bookr project directory, then execute the following command to create the reviews app:

python3 manage.py startapp reviews

Note

After creating the reviews app, the files in your bookr project directory would look like this: http://packt.live/3nZGy5D.

There is no output if the command was successful, but a reviews app directory has been created. You can look inside this directory to see the files that were created: the migrations directory, admin.py, models.py, and so on. We'll examine these in detail in the Django Apps section.

In this exercise, we created the bookr project, tested that the project was working by starting the Django dev server, then created the reviews app for the project. Now that we've had some hands-on time with a Django project, we'll return to some of the theory behind Django's design and HTTP requests and responses.

Model View Template

A common design pattern in application design is Model View Controller (MVC), where the model of the application (its data) is displayed in one or more views and a controller marshals interaction between the model and view. Django follows a somewhat similar paradigm called Model View Template (MVT).

Like MVC, MVT also uses models for storing data. However, with MVT, a view will query a model and then render it with a template. Usually, with MVC languages, all three components need to be developed with the same language. With MVT, the template can be in a different language. In the case of Django, the models and views are written in Python and the Template in HTML. This means that a Python developer could work on the models and views, while a specialist HTML developer works on the HTML. We'll first explain models, views, and templates in more detail, and then look at some example scenarios where they are used.

Models

Django models define the data for your application and provide an abstraction layer to SQL database access through an Object Relational Mapper (ORM). An ORM lets you define your data schema (classes, fields, and their relationships) using Python code, without needing an understanding of the underlying database. This means you can define your database layer in Python code and Django will take care of generating SQL queries for you. ORMs will be discussed in detail in Chapter 2, Models and Migrations.

Note

SQL stands for Structured Query Language and is a way of describing a type of database that stores its data in tables, with each table having several rows. Think of each table being like an individual spreadsheet. Unlike a spreadsheet, though, relationships can be defined between the data in each table. You can interact with data by executing SQL queries (often referred to as just queries when talking about databases). Queries allow you to retrieve data (SELECT), add or change data (INSERT and UPDATE respectively), and remove data (DELETE). There are many SQL database servers to choose from, such as SQLite, PostgreSQL, MySQL, or Microsoft SQL Server. Much of the SQL syntax is similar between databases, but there can be some differences in dialect. Django's ORM takes care of these differences for you: when we start coding, we will use the SQLite database to store data on disk, but later when we deploy to a server, we will switch to PostgreSQL but won't need to make any code changes.

Normally, when querying a database, the results come back as primitive Python objects, (for example, lists of strings, integers, floats, or bytes). When using the ORM, results are automatically converted into instances of the model classes you have defined. Using an ORM means that you are automatically protected from a type of vulnerability known as a SQL injection attack.

If you're more familiar with databases and SQL, you always have the option of writing your own queries too.

Views

A Django view is where most of the logic for your application is defined. When a user visits your site, their web browser will send a request to retrieve data from your site (in the next section, we will go into more detail on what an HTTP request is and what information it contains). A view is a function that you write that will receive this request in the form of a Python object (specifically, a Django HttpRequest object). It is up to your view to decide how it should respond to the request and what it should send back to the user. Your view must return an HttpResponse object that encapsulates all the information being provided to the client: content, HTTP status, and other headers.

The view can also optionally receive information from the URL of the request, for example, an ID number. A common design pattern of a view is to query a database via the Django ORM using an ID that is passed into your view. Then the view can render a template (more on this in a moment) by providing it with data from the model retrieved from the database. The rendered template becomes the content of HttpResponse and is returned from the view function. Django takes care of the communication of the data back to the browser.

Templates

A template is a HyperText Markup Language (HTML) file (usually – any text file can be a template) that contains special placeholders that are replaced by variables your application provides. For example, your application could render a list of items in either a gallery layout or a table layout. Your view would fetch the same models for either one but would be able to render a different HTML file with the same information to present the data differently. Django emphasizes safety, so it will take care of automatically escaping variables for you. For example, the < and > symbols (among others) are special characters in HTML. If you try to use them in a variable, then Django automatically encodes them so they render correctly in a browser.

MVT in Practice

We'll now look at some examples to illustrate how MVT works in practice. In the examples, we have a Book model that stores information about different books, and a Review model that stores information about different reviews of the books.

In the first example, we want to be able to edit the information about a book or review. Take the first scenario, editing a book's details. We would have a view to fetch the Book data from the database and provide the Book model. Then, we would pass context information containing the Book object (and other data) to a template that would show a form to capture the new information. The second scenario (editing a review) is similar: fetch a Review model from the database, then pass the Review object and other data to a template to display an edit form. These scenarios might be so similar that we can reuse the same template for both. Refer to Figure 1.3.

Figure 1.3: Editing a single book or review

You can see here that we use two models, two views, and one template. Each view fetches a single instance of its associated model, but they can both use the same template, which is a generic HTML page to display a form. The views can provide extra context data to slightly alter the display of the template for each model type. Also illustrated in the diagram are the parts of the code that are written in Python and those that are written in HTML.

In the second example, we want to be able to show the user a list of the books or reviews that are stored in the application. Furthermore, we want to allow the user to search for books and get a list of all that match their criteria. We will use the same two models as the previous example (Book and Review), but we will create new views and templates. Since there are three scenarios, we'll use three views this time: the first fetches all books, the second fetches all reviews, and the last searches for books based on some search criteria. Once again, if we write a template well, we might be able to just use a single HTML template again. Refer to Figure 1.4:

Figure 1.4: Viewing multiple books or reviews

The Book and Review models remain unchanged from the previous example. The three views will fetch many (zero or more) books or reviews. Then, each view can use the same template, which is a generic HTML file that iterates over a list of objects that it is given and renders them. Once again, the views can send extra data in the context to alter how the template behaves, but the majority of the template will be as generic as possible.

In Django, a model does not always need to be used to render an HTML template. A view can generate the context data itself and render a template with it, without requiring any model data. See Figure 1.5 for a view sending data straight to a template:

Figure 1.5: From view to template without a model

In this example, there is a welcome view to welcome a user to the site. It doesn't need any information from the database, so it can just generate the context data itself. The context data depends on the type of information you want to display; for example, you could pass the user information to greet them by name if they are logged in. It is also possible for a view to render a template without any context data. This can be useful if you have static information in an HTML file that you want to serve.

Introduction to HTTP

Now that you have been introduced to MVT in Django, we can look at how Django processes an HTTP request and generates an HTTP response. But first, we need to explain in more detail what HTTP requests and responses are, and what information they contain.

Let's say someone wants to visit your web page. They type in its URL or click a link to your site from a page they are already on. Their web browser creates an HTTP request, which is sent to the server hosting your website. Once a web server receives the HTTP request from your browser, it can interpret it and then send back a response. The response that the server sends might be simple, such as just reading an HTML or image file from disk and sending it. Or, the response might be more complex, maybe using server-side software (such as Django) to dynamically generate the content before sending it:

Figure 1.6: HTTP request and HTTP response

The request is made up of four main parts: the method, path, headers, and body. Some types of requests don't have a body. If you just visit a web page, your browser will not send a body, whereas if you are submitting a form (for example, by logging into a site or performing a search), then your request will have a body containing the data you're submitting. We'll look at two example requests now to illustrate this.

The first request will be to an example page with the URL https://www.example.com/page. When your browser visits that page, behind the scenes, this is what it's sending:

GET /page HTTP/1.1

Host: www.example.com

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Firefox/15.0.1

Cookie: sessid=abc123def456

The first line contains the method (GET) and the path (/page). It also contains the HTTP version, in this case, 1.1, although you don't have to worry about this. Many different HTTP methods can be used, depending on how you want to interact with the remote page. Some common ones are GET (retrieve the remote page), POST (send data to the remote page), PUT (create a remote page), and DELETE (delete the remote page). Note that the descriptions of the actions are somewhat simplified—the remote server can choose how it responds to different methods, and even experienced developers can disagree on the correct method to implement for a particular action. It's also important to note that even if a server supports a particular method, you will probably need the correct permissions to perform that action—you can't just use DELETE on a web page you don't like, for example.

When writing a web application, the vast majority of the time, you will only deal with GET requests. When you start accepting forms, you'll also have to use POST requests. It is only when you are working with advanced features such as creating REST APIs that you will have to worry about PUT, DELETE, and other methods.

Referring back to the example request again, from line 2 onward are the headers of the request. The headers contain extra metadata about the request. Each header is on its own line, with the header name and its value separated by a colon. Most are optional (except for Host—more on that soon). Header names are not case sensitive. For the sake of the example, we're only showing three common headers here. Let's look at the example headers in order:

Host: As mentioned, this is the only header that is required (for HTTP 1.1 or later). It is needed for the webserver to know which website or application should respond to the request, in case there are multiple sites hosted on a single server.User-Agent: Your browser usually sends to the server a string identifying its version and operating system. Your server application could use this to serve different pages to different devices (for example, a mobile-specific page for smartphones).Cookie: You have probably seen a message when visiting a web page that lets you know that it is storing a cookie in the browser. These are small pieces of information that a website can store in your browser that can be used to identify you or save settings for when you return to the site. If you were wondering about how your browser sends these cookies back to the server, it is through this header.

There are many other standard headers defined and it would take up too much space to list them all. They can be used to authenticate to the server (Authorization), tell the server what kind of data you can receive (Accept), or even state what language you'd like for the page (Accept-Language, although this will only work if the page creator has made the content available in the particular language you request). You can even define your own headers that only your application knows how to respond to.