Руководство по Django
Изучите Django с нуля: установка фреймворка, создание моделей, представлений, шаблонов, миграции и запуск рабочего веб-приложения.
Django — это высокоуровневый веб-фреймворк Python, позволяющий быстро создавать безопасные и масштабируемые веб-приложения. Он следует архитектурному паттерну Model-Template-View (MTV) — близкому родственнику MVC — и поставляется со встроенными ORM, панелью администратора, маршрутизацией URL, аутентификацией и многим другим. Принцип «batteries-included» в Django означает, что вы тратите время на логику приложения, а не на сборку инфраструктуры.
Это руководство проводит через основные шаги: установку Django в виртуальном окружении, создание проекта и приложения, определение моделей, написание представлений, создание шаблонов, запуск миграций базы данных и проверку результата в браузере.
Почему стоит использовать Django
Всё включено
Django поставляется со встроенной панелью администратора, аутентификацией пользователей, обработкой форм, ORM, поддержкой кэширования и утилитами для интернационализации. Нет необходимости искать сторонние пакеты для покрытия этих основ.
Безопасность по умолчанию
Django защищает от SQL-инъекций, используя параметризованные запросы через ORM. Также имеется встроенная защита от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и кликджекинга. Секретный ключ, режим DEBUG и настройки ALLOWED_HOSTS дополнительно сокращают поверхность атаки.
Масштабируемость
Django используется на сайтах с высокой нагрузкой, в том числе Instagram и Disqus. Его фреймворк кэширования интегрируется с Memcached и Redis, а ORM поддерживает пул соединений с базой данных. Вы можете масштабироваться вертикально или горизонтально, не меняя код приложения.
Большая экосистема
Индекс пакетов Django содержит тысячи сторонних приложений — REST API (djangorestframework), обработка изображений, платёжные шлюзы и многое другое. Стабильность фреймворка и длинный цикл выпуска означают, что эти пакеты активно поддерживаются.
Как работает паттерн MTV в Django
| Слой | Термин Django | Ответственность |
|---|---|---|
| Данные | Model | Класс Python, соответствующий таблице базы данных |
| Представление | Template | HTML-файл с плейсхолдерами {{ variable }} |
| Логика | View | Функция (или класс) Python, читающая данные и возвращающая ответ |
Диспетчер URL (urls.py) сопоставляет пути входящих запросов с нужными представлениями. Представление запрашивает модели, затем передаёт данные в шаблон. Отрендеренный HTML возвращается браузеру.
Настройка виртуального окружения
Всегда изолируйте проекты Django в виртуальном окружении, чтобы зависимости не конфликтовали между проектами.
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
venv\Scripts\activate # WindowsПосле активации в строке приглашения появляется (venv). Каждая команда pip install с этого момента влияет только на данное окружение.
Установка Django
При активном виртуальном окружении установите Django с помощью pip:
pip install djangoПроверьте установку:
python -m django --versionDjango выведет строку с версией, например 5.1.4.
Создание проекта Django
Проект — это контейнер верхнего уровня для всего вашего сайта. Создайте его командой:
django-admin startproject mysite
cd mysiteЭто создаёт следующую структуру:
mysite/
├── manage.py # Command-line utility for this project
└── mysite/
├── __init__.py
├── settings.py # Project configuration (database, installed apps, …)
├── urls.py # Root URL dispatcher
├── asgi.py # ASGI entry point
└── wsgi.py # WSGI entry pointmanage.py — ваш основной инструмент для выполнения команд: запуска сервера разработки, создания миграций и создания суперпользователя. Внутренняя папка mysite/ является Python-пакетом самого проекта.
Создание приложения Django
Проект может содержать несколько приложений — самодостаточных модулей, каждый из которых отвечает за одну функциональную область. Создайте приложение blog:
python manage.py startapp blogЗарегистрируйте его, чтобы Django мог найти его модели, шаблоны и статические файлы. Откройте mysite/settings.py и добавьте 'blog' в INSTALLED_APPS:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # <-- add this line
]Директория приложения после создания выглядит так:
blog/
├── __init__.py
├── admin.py # Register models with the admin interface
├── apps.py # App configuration
├── migrations/ # Auto-generated migration files
│ └── __init__.py
├── models.py # Database models
├── tests.py
└── views.py # View functionsОпределение моделей
Модель — это класс Python, наследующий django.db.models.Model. Каждый атрибут класса соответствует столбцу в базе данных. ORM Django переводит ваш Python-код в SQL и обрабатывает все взаимодействия с базой данных.
Откройте blog/models.py и определите модель Post:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-date_posted'] # Newest posts firstКлючевые типы полей, используемые здесь:
| Поле | Назначение |
|---|---|
CharField(max_length=N) | Короткий текст с максимальной длиной |
TextField() | Текст неограниченной длины |
ForeignKey(…, on_delete=CASCADE) | Связь «многие к одному»; удаляет посты при удалении их автора |
DateTimeField(auto_now_add=True) | Устанавливается один раз при создании записи |
DateTimeField(auto_now=True) | Обновляется при каждом сохранении записи |
Метод __str__ управляет тем, как объект отображается в панели администратора и в оболочке Python.
Запуск миграций
После определения или изменения моделей необходимо создать и применить миграции — версионированные инструкции для обновления схемы базы данных.
# Generate a new migration file from your model changes
python manage.py makemigrations
# Apply all pending migrations to the database
python manage.py migrateВы увидите вывод наподобие:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OKЗапускайте migrate каждый раз, когда добавляете, удаляете или изменяете поля модели. Никогда не редактируйте файлы миграций вручную, если вы не полностью понимаете их SQL.
Использование панели администратора Django
Встроенный интерфейс администратора позволяет создавать, читать, обновлять и удалять записи через браузер — без необходимости создавать пользовательский интерфейс. Зарегистрируйте модель Post в blog/admin.py:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date_posted')
list_filter = ('date_posted', 'author')
search_fields = ('title', 'content')Создайте учётную запись суперпользователя для входа:
python manage.py createsuperuserDjango запросит имя пользователя, email и пароль. Затем запустите сервер разработки и перейдите на http://127.0.0.1:8000/admin/:
python manage.py runserverВойдите с учётными данными суперпользователя — вы увидите модель Posts в разделе «Blog».
Написание представлений
Представление — это функция (или класс) Python, принимающая HTTP-запрос и возвращающая HTTP-ответ. Откройте blog/views.py:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
"""Display all published posts, newest first."""
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
"""Display a single post by primary key."""
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})get_object_or_404 — полезный ярлык: он извлекает объект из базы данных или автоматически возвращает ответ 404, если объект не существует. Третий аргумент render — это словарь контекста: его ключи становятся переменными шаблона.
Создание шаблонов
Шаблоны — это HTML-файлы, содержащие теги Django Template Language (DTL). Создайте следующую структуру директорий:
blog/
└── templates/
└── blog/
├── base.html
├── post_list.html
└── post_detail.htmlblog/templates/blog/base.html — общий макет:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
<header><h1>My Blog</h1></header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
blog/templates/blog/post_list.html — страница со списком:
{% extends "blog/base.html" %}
{% block title %}All Posts{% endblock %}
{% block content %}
{% for post in posts %}
<article>
<h2><a href="/blog/{{ post.pk }}/">{{ post.title }}</a></h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
{% empty %}
<p>No posts yet.</p>
{% endfor %}
{% endblock %}
blog/templates/blog/post_detail.html — страница детального просмотра:
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h2>{{ post.title }}</h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<div>{{ post.content }}</div>
<a href="/">Back to all posts</a>
{% endblock %}
Ключевые возможности DTL, использованные выше:
| Тег / Фильтр | Что делает |
|---|---|
{% extends "…" %} | Наследование от базового шаблона |
{% block name %} | Определение заменяемой секции |
{{ variable }} | Вывод значения (автоматически экранируется в HTML) |
{% for … %} / {% empty %} | Цикл с обработкой пустых списков |
|date:"N j, Y" | Форматирование значения datetime |
|truncatewords:30 | Сокращение текста до 30 слов |
Настройка URL
Конфигурация URL сопоставляет пути запросов с функциями представлений.
blog/urls.py — создайте этот файл в директории blog:
from django.urls import path
from . import views
app_name = 'blog' # Enables namespaced URL reversing
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]mysite/urls.py — включите URL приложения в корневой файл проекта:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
path('', include('blog.urls', namespace='blog_root')),
]Конвертер пути <int:pk> захватывает целое число из URL и передаёт его как именованный аргумент pk в post_detail.
Проверка полного цикла работы
Запустите сервер разработки:
python manage.py runserverЗатем откройте http://127.0.0.1:8000/ в браузере. Если постов ещё нет, шаблон покажет "No posts yet." Войдите на http://127.0.0.1:8000/admin/ и добавьте пост. Обновите главную страницу — пост появится немедленно.
Жизненный цикл запроса к главной странице выглядит так:
- Браузер отправляет
GET / - Диспетчер URL Django сопоставляет
''и вызываетpost_list post_listвыполняетPost.objects.all()(переводится вSELECT * FROM blog_post ORDER BY date_posted DESC)- Django рендерит
post_list.html, вставляя посты в шаблон - Отрендеренный HTML возвращается браузеру
Шпаргалка по запросам ORM Django
ORM позволяет строить SQL-запросы с помощью цепочек Python-методов. Знание наиболее распространённых выборок существенно экономит время:
# All posts
Post.objects.all()
# Posts by a specific author
Post.objects.filter(author__username='alice')
# Posts containing a word in the title (case-insensitive)
Post.objects.filter(title__icontains='django')
# The five most recent posts
Post.objects.order_by('-date_posted')[:5]
# Count posts
Post.objects.count()
# Get one object (raises DoesNotExist if not found)
Post.objects.get(pk=1)
# Exclude posts by a specific author
Post.objects.exclude(author__username='alice')Каждый из этих запросов генерирует SQL только при вычислении набора запросов (при итерации, срезе или преобразовании в список). Это называется ленивым вычислением и позволяет свести к минимуму лишние обращения к базе данных.
Итоговая структура проекта
После завершения этого руководства структура проекта выглядит следующим образом:
mysite/
├── manage.py
├── mysite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── blog/
├── admin.py
├── migrations/
│ └── 0001_initial.py
├── models.py
├── templates/
│ └── blog/
│ ├── base.html
│ ├── post_list.html
│ └── post_detail.html
├── urls.py
└── views.pyРаспространённые ошибки
Забыть зарегистрировать приложение. Если 'blog' отсутствует в INSTALLED_APPS, Django не найдёт его модели или шаблоны, и makemigrations не выдаст никакого вывода для этого приложения.
Пропустить migrate после makemigrations. Выполнение только makemigrations создаёт файл миграции, но не затрагивает базу данных. Всегда следуйте за этим шагом командой migrate.
Ошибки «шаблон не найден». Django ищет шаблоны внутри директории templates/ каждого приложения. Дополнительная подпапка blog/ внутри templates/ (templates/blog/post_list.html) — это соглашение, предотвращающее коллизии имён между приложениями; не пропускайте её.
DEBUG = True в production. Сервер разработки и DEBUG = True раскрывают трассировки стека всем желающим. Установите DEBUG = False и настройте ALLOWED_HOSTS перед развёртыванием.
Следующие шаги
- Модули Python — поймите, как система модулей Python лежит в основе структуры импортов Django.
- Python PIP — управляйте Django и его зависимостями.
- Виртуальные окружения Python — изолируйте каждый проект Django.
- MySQL с Python — замените SQLite на базу данных производственного уровня.
- MongoDB с Python — используйте NoSQL-бэкенд с Django.
Официальная документация Django на docs.djangoproject.com охватывает представления на основе классов, формы, аутентификацию, REST API с Django REST Framework и развёртывание в production — всё это логичные следующие шаги, когда вы освоитесь с основами, рассмотренными здесь.