0% completed
What is Django?
On This Page
Why a Framework Helps: A Blog Example
Two Ideas Behind Django
Key Features of Django
Rapid Development
Security
Scalability
Object-Relational Mapping (ORM)
Built-in Admin Interface
Versatile and Extensible
Community and Documentation
Installing Django and Creating a Project
A Custom User Model Before the First Migration
Every website that stores data and shows pages to users repeats the same work. It reads the address the browser asked for, picks the code that should answer, reads and writes a database, builds an HTML page, checks who the user is, and defends itself against common attacks. A library that does this repeated work for you, and leaves you to write only the parts that are specific to your site, is called a web framework.
Django is a web framework written in Python. It was built for fast development and a clean, practical design. Because Django already handles routing, database access, user accounts, and security, you spend your time on the logic of your own application instead of writing those parts again.
Why a Framework Helps: A Blog Example
Suppose you want to build a blog where authors publish articles and readers browse them. Without a framework, you would write code to match each URL to a function, open database connections and write SQL by hand, hash and check passwords, and escape every value you put into an HTML page. Each of those jobs is easy to get slightly wrong, and a small mistake in password handling or escaping becomes a security hole.
With Django, the blog starts from working parts. You describe an Article as a Python class and Django creates the database table for it. You write a short function that lists articles and Django connects it to a URL. Django's login system and its admin site, a ready-made web interface for adding and editing records, are available from the first day. This course builds exactly that blog, one chapter at a time.
Two Ideas Behind Django
Django describes itself as batteries-included. That means the parts most websites need ship with the framework, so you do not have to choose and connect separate libraries for each one. The included parts cover a database layer, an admin interface, forms, authentication, sessions, caching, and protection against common web attacks.
Django also follows the principle "Don't Repeat Yourself" (DRY). You define each piece of information in one place, and the rest of the framework reads it from there. For example, the fields of the Article class decide the columns of the database table. The admin site and the forms built from that class read their field types from the same definition, so you never describe the title field three times.
Key Features of Django
Rapid Development
Authentication, an admin panel, and form handling are part of the framework, so you do not build them from scratch. A first working version of an application therefore takes far less code than it would without a framework. You then spend your effort on the features that make your application different from others.
Security
Django protects against several common web attacks by default:
- SQL injection, where an attacker changes a database query by typing SQL into a form field. Django's database layer sends values separately from the query text, so typed input is never run as SQL.
- Cross-site scripting (XSS), where an attacker stores a script that later runs in other users' browsers. Django templates escape HTML characters in every value they print unless you say otherwise.
- Cross-site request forgery (CSRF), where another site tricks a signed-in user's browser into submitting a form to your site. Django rejects a form submission that does not carry a secret token issued by your own site.
- Clickjacking, where another site shows your pages inside a hidden frame to trick users into clicking. Django adds a response header that tells browsers not to show your pages inside a frame on another site.
These protections come from Django's default settings and middleware, so you receive them without being a security expert. You can still switch a protection off by mistake, so later lessons point out where that can happen.
Scalability
Django runs small personal sites and very busy ones. Its components are loosely tied together, so a growing site can add more application servers behind a load balancer, put a cache in front of the database, or move the database to its own machine. The Django project lists Instagram, Mozilla, Pinterest, and Disqus among the sites that use it.
Object-Relational Mapping (ORM)
Django includes an Object-Relational Mapper (ORM), a layer that turns Python classes and method calls into database tables and SQL queries. You read and write data with Python code such as Article.objects.all() instead of writing SQL. The same code works with each database Django supports, including PostgreSQL, MySQL, and SQLite, so you can move between them with few code changes.
The ORM also makes queries easier to read and maintain, and it removes the most common cause of SQL injection, which is building SQL by joining strings.
Built-in Admin Interface
Django can generate an admin interface for your models. It is a set of web pages where staff users add, edit, and delete records without writing any queries. In the blog, an editor can use it to correct an article's title or remove a spam comment, and you do not have to build a separate dashboard for that work.
Versatile and Extensible
Django is used for many kinds of applications, such as content management systems, social platforms, online shops, internal data tools, and REST APIs for mobile and web clients. Its apps are separate packages, so you can add features from third-party packages, for example Django REST Framework for APIs, which this course uses later.
Community and Documentation
Django has an active community and detailed official documentation at docs.djangoproject.com. When you meet a problem, the documentation, the Django Forum, and Stack Overflow usually have an answer. The documentation is organized by Django version, so make sure the page you read matches the version you installed.
Installing Django and Creating a Project
The rest of this chapter refers to a real project, so create it now. Current Django needs Python 3.12 or newer. Check your version with python --version (on some macOS and Linux systems the command is python3).
First, create a virtual environment, a private folder of packages for one project, so that the packages you install here do not mix with other projects:
mkdir blog-project cd blog-project python -m venv .venv
Activate the environment. The command differs between operating systems:
# macOS and Linux source .venv/bin/activate # Windows (PowerShell) .venv\Scripts\Activate.ps1
With the environment active, install Django and check the installed version:
pip install django python -m django --version
6.1.3
Now create a project. A Django project is the whole website: its settings, its top-level URL list, and the files a server needs to run it. The django-admin command came with Django:
django-admin startproject mysite cd mysite
Inside the new project, create an app. An app is a Python package that does one job for the site, such as the blog, the user accounts, or the shop. One project can hold many apps, and one app can be reused in other projects. The manage.py script runs Django commands for this project:
python manage.py startapp blog
The folder now looks like this:
mysite/ the outer folder, a container you can rename manage.py runs Django commands for this project mysite/ the project package __init__.py settings.py all configuration: apps, database, middleware, templates urls.py the top-level list of URL patterns asgi.py entry point for ASGI web servers wsgi.py entry point for WSGI web servers blog/ the app you just created __init__.py admin.py registers models with the admin site apps.py the app's configuration migrations/ database change files, explained in Chapter 2 __init__.py models.py the app's data models tests.py the app's tests views.py the app's views
The diagram separates the two kinds of folder. Notice that the settings and the top-level URL list belong to the project, while models and views belong to an app.
Django does not use an app until you list it in the project settings. Open mysite/settings.py and add 'blog' to the end of INSTALLED_APPS:
# mysite/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', ]
The six entries above 'blog' are Django's own apps: the admin site, authentication, content types, sessions, messages, and static files. They are the batteries described earlier, and they are switched on in every new project.
A Custom User Model Before the First Migration
The project has no database tables yet, and one decision has to come before the first ones are made. Django ships a User model for login accounts, and a project can replace it with a class of its own through a setting called AUTH_USER_MODEL. Django's documentation recommends a custom user model for every new project. Replacing the user model after the first migration is hard, because the built-in tables already point at the old one, while adding a field to a model you already own is an ordinary change. Chapter 6 explains users in detail, so for now you only create the class.
The user model gets an app of its own, called accounts:
python manage.py startapp accounts
Add it to INSTALLED_APPS, below 'blog':
# mysite/settings.py INSTALLED_APPS = [ # ...Django's six apps, as above... 'blog', 'accounts', ]
The model inherits from AbstractUser, which already has every field and method of Django's own User, such as the username and the password. The class adds nothing yet, so its body is only pass:
# accounts/models.py from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass
Register it with the admin site, using UserAdmin, the same admin page that Django uses for its own user model:
# accounts/admin.py from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import User admin.site.register(User, UserAdmin)
Finally, tell Django to use this class. Add the setting at the end of settings.py. Its value is the app label, a dot, and the model name:
# mysite/settings.py AUTH_USER_MODEL = "accounts.User"
Now create the database. The first command writes a migration file for the new model, and the second creates the tables; Chapter 2 explains both commands in detail:
python manage.py makemigrations python manage.py migrate
Migrations for 'accounts': accounts/migrations/0001_initial.py + Create model User Operations to perform: Apply all migrations: accounts, admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0001_initial... OK ... Applying auth.0012_alter_user_first_name_max_length... OK Applying accounts.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying sessions.0001_initial... OK
The accounts are stored in a table called accounts_user, and Django's own auth_user table is never created. Notice that accounts.0001_initial runs before the admin's migrations, because the admin's log of changes points at a user. For the same reason, the order of the two commands matters. Until accounts has its migration file, migrate and runserver both stop with ValueError: Dependency on app with no migrations: accounts.
Now start the development server:
python manage.py runserver
Performing system checks... System check identified no issues (0 silenced). Django version 6.1.3, using settings 'mysite.settings' Starting WSGI development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. WARNING: This is a development server. Do not use it in a production setting. Use a production WSGI or ASGI server instead.
The output is shortened here. The real output also starts with a line about watching for file changes, and it shows the current date and time above the Django version. On Windows, the quit line reads "Quit the server with CTRL-BREAK." instead.
Open http://127.0.0.1:8000/ in a browser. Django shows a welcome page titled "The install worked successfully! Congratulations!", which appears only while DEBUG is True and the project has no URL patterns besides the admin site. The output has no warning about unapplied migrations, because migrate has already created every table in the SQLite file db.sqlite3. If you start the server before you migrate, it warns that the project has 19 unapplied migrations. Press CONTROL-C to stop the server.
As the last line of the output says, runserver is for development only. It restarts itself when you change a file, but it is not built for the security and load of a public website.
Reading Progress
0%
On This Page
Why a Framework Helps: A Blog Example
Two Ideas Behind Django
Key Features of Django
Rapid Development
Security
Scalability
Object-Relational Mapping (ORM)
Built-in Admin Interface
Versatile and Extensible
Community and Documentation
Installing Django and Creating a Project
A Custom User Model Before the First Migration