10 KiB
status, type, tags, created, updated, source, aliases
| status | type | tags | created | updated | source | aliases | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| processing | concept |
|
2026-05-30 | 2026-06-05 |
|
|
Django: Представления, шаблоны и CBV
Маршрутизация (URL Routing)
- Описывается в
urlpatternsс помощьюpath()иre_path(). - Конвертеры:
<int:pk>,<slug:slug>,<uuid:id>. - Включение других файлов:
path('blog/', include('blog.urls')). - Реверсирование:
{% url 'name' %}в шаблонах илиreverse('name')в Python.
Конвертеры вытаскивают часть URL, проверяют её тип и передают во view как аргумент:
<str:name>— непустая строка без/; используется по умолчанию.<int:pk>— целое положительное число.<slug:slug>— строка для человекочитаемого URL: буквы, цифры,_,-.<uuid:id>— UUID, например075194d3-6885-417e-a8a8-6c931e272f00.<path:subpath>— строка, которая может содержать/.
Маршрутизация связывает URL с view-функцией или view-классом. Имя маршрута (name) нужно, чтобы не хардкодить URL в коде и шаблонах.
# project/urls.py
from django.urls import include, path
urlpatterns = [
path("blog/", include("blog.urls")),
]
# blog/urls.py
from django.urls import path
from . import views
app_name = "blog"
urlpatterns = [
path("", views.post_list, name="post_list"),
path("<int:pk>/", views.post_detail, name="post_detail"),
path("tag/<slug:slug>/", views.posts_by_tag, name="posts_by_tag"),
path("files/<path:subpath>/", views.file_detail, name="file_detail"),
]
def post_detail(request, pk):
# pk уже int
...
def posts_by_tag(request, slug):
# slug — строка из URL
...
from django.urls import reverse
url = reverse("blog:post_detail", kwargs={"pk": 1})
path() обычно принимает:
route— строка маршрута;view— функция илиClassView.as_view();kwargs— дополнительные аргументы view;name— имя маршрута для{% url %}иreverse().
app_name задаёт namespace приложения. Тогда маршрут вызывается как blog:post_detail, а не просто post_detail.
Представления (Views)
Views принимают HttpRequest и возвращают HttpResponse.
View — это точка входа для запроса. В ней обычно читают данные из БД, проверяют условия и возвращают HTML, JSON, редирект или ошибку.
Функциональные представления (FBV)
FBV — обычная функция. Удобна, когда логика короткая и нестандартная.
from django.shortcuts import render, get_object_or_404
def index(request):
latest_items = Model.objects.all()[:5]
return render(request, "app/index.html", {"items": latest_items})
У render() первым аргументом должен идти request:
return render(request, "index.html", context)
from django.shortcuts import get_object_or_404, render
from .models import Post
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, "blog/detail.html", {"post": post})
Классовые представления (CBV)
Абстрагируют типичные задачи. Вызываются в URL через .as_view().
- TemplateView: Отображение статического шаблона.
- ListView: Автоматический список объектов (данные в
object_list). - DetailView: Детальная информация об одном объекте (ищет по
pkилиslug).
CBV — класс с готовым поведением. Django сам вызывает нужные методы класса: например, get() для GET-запроса или get_queryset() для получения списка объектов.
Пример ListView:
from django.views.generic import DetailView, ListView, TemplateView
from .models import Post
class AboutView(TemplateView):
template_name = "blog/about.html"
class PostListView(ListView):
model = Post
template_name = "blog/list.html"
context_object_name = "posts"
paginate_by = 10
def get_queryset(self):
return Post.objects.filter(is_published=True).order_by("-created_at")
class PostDetailView(DetailView):
model = Post
template_name = "blog/detail.html"
context_object_name = "post"
Если в ListView не указать ни model, ни queryset, Django не поймёт, какие объекты показывать, и выдаст ошибку.
Стандартные имена в контексте:
ListView—object_listи дополнительно<model>_list, напримерpost_list;DetailView—objectи дополнительно<model>, напримерpost.
Методы, которые часто переопределяют:
get_queryset()— изменить список объектов;get_object()— изменить получение одного объекта;get_context_data()— добавить данные в шаблон.
При переопределении get_context_data() обычно сначала вызывают базовую логику:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Посты"
return context
Паджинация в ListView включается через paginate_by = 10. В шаблоне появляются page_obj, paginator, is_paginated.
Шаблоны по умолчанию:
ListViewищет<app>/<model>_list.html;DetailViewищет<app>/<model>_detail.html.
# blog/urls.py
from django.urls import path
from .views import AboutView, PostDetailView, PostListView
app_name = "blog"
urlpatterns = [
path("about/", AboutView.as_view(), name="about"),
path("", PostListView.as_view(), name="post_list"),
path("<int:pk>/", PostDetailView.as_view(), name="post_detail"),
]
Шаблоны (Templates)
Используют Django Template Language (DTL).
Синтаксис
- Переменные:
{{ var.attr }}. - Теги:
{% if %},{% for %},{% url %},{% csrf_token %}. - Фильтры:
{{ date|date:"Y-m-d" }},{{ list|length }},{{ text|lower }}.
Шаблон получает контекст из view. Например, если view передала {"posts": posts}, в шаблоне доступна переменная posts.
Если обратиться к переменной, которой нет в контексте, Django-шаблон обычно выведет пустую строку, а не Python-ошибку.
{% for post in posts %}
<article>
<h2>
<a href="{% url 'blog:post_detail' post.pk %}">
{{ post.title|upper }}
</a>
</h2>
{% if post.is_published %}
<p>{{ post.created_at|date:"Y-m-d" }}</p>
{% endif %}
</article>
{% empty %}
<p>Постов нет.</p>
{% endfor %}
Наследование шаблонов
Позволяет избежать дублирования HTML-кода.
- Базовый шаблон (
base.html): Определяет блоки{% block content %}{% endblock %}. - Дочерний шаблон: Использует
{% extends "base.html" %}и переопределяет блоки.
<!-- templates/base.html -->
<!doctype html>
<html lang="ru">
<head>
<title>{% block title %}Сайт{% endblock %}</title>
</head>
<body>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
<!-- templates/blog/list.html -->
{% extends "base.html" %}
{% block title %}Посты{% endblock %}
{% block content %}
<h1>Посты</h1>
{% for post in posts %}
<a href="{% url 'blog:post_detail' post.pk %}">
{{ post.title }}
</a>
{% endfor %}
{% endblock %}
Статические файлы (Static)
- Подключаются через
{% load static %}. - Настройки в
settings.py:STATIC_URL,STATICFILES_DIRS. - В продакшне используется команда
python manage.py collectstatic.
Статика — это CSS, JavaScript, изображения и другие файлы, которые не генерируются view.
# settings.py
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
{% load static %}
<link rel="stylesheet" href="{% static 'css/app.css' %}">
<script src="{% static 'js/app.js' %}"></script>
python manage.py collectstatic
Простыми словами для экзамена
FBV — view как функция. CBV — view как класс с готовой логикой.
Маршрут соединяет URL и view:
path("find/", views.find, name="find")
В шаблоне ссылка на именованный маршрут создаётся так:
<a href="{% url 'myapp:find' %}">Поиск</a>
Шаблонные переменные пишутся через {{ variable }}. Шаблонные теги пишутся через {% tag %}. Комментарии пишутся через {# comment #}.
Ключ словаря в шаблоне читается через точку:
{{ user_data.name }}