35,99 €
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:
Seitenzahl: 864
Veröffentlichungsjahr: 2021
Learn to build modern web applications with a Python-based framework
Ben Shaw, Saurabh Badhwar, Andrew Bird, Bharath Chandra K S, and Chris Guest
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
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.
"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.
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.
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.
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.
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.
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.
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.
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.
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.
