--- status: processing type: concept tags: - django - routing - templates - cbv - fbv created: 2026-05-30 updated: 2026-06-05 source: - '[[lec2-django_lec_urls_views_templates-1.pdf]]' - '[[lec3-django_cbv-1.pdf]]' - '[[p4-django_cbv-1.pdf]]' aliases: - 'Django: Представления, шаблоны и CBV' --- # Django: Представления, шаблоны и CBV ## Маршрутизация (URL Routing) - Описывается в `urlpatterns` с помощью `path()` и `re_path()`. - Конвертеры: ``, ``, ``. - Включение других файлов: `path('blog/', include('blog.urls'))`. - Реверсирование: `{% url 'name' %}` в шаблонах или `reverse('name')` в Python. Конвертеры вытаскивают часть URL, проверяют её тип и передают во view как аргумент: - `` — непустая строка без `/`; используется по умолчанию. - `` — целое положительное число. - `` — строка для человекочитаемого URL: буквы, цифры, `_`, `-`. - `` — UUID, например `075194d3-6885-417e-a8a8-6c931e272f00`. - `` — строка, которая может содержать `/`. Маршрутизация связывает URL с view-функцией или view-классом. Имя маршрута (`name`) нужно, чтобы не хардкодить URL в коде и шаблонах. ```python # project/urls.py from django.urls import include, path urlpatterns = [ path("blog/", include("blog.urls")), ] ``` ```python # blog/urls.py from django.urls import path from . import views app_name = "blog" urlpatterns = [ path("", views.post_list, name="post_list"), path("/", views.post_detail, name="post_detail"), path("tag//", views.posts_by_tag, name="posts_by_tag"), path("files//", views.file_detail, name="file_detail"), ] ``` ```python def post_detail(request, pk): # pk уже int ... def posts_by_tag(request, slug): # slug — строка из URL ... ``` ```python 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 — обычная функция. Удобна, когда логика короткая и нестандартная. ```python 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`: ```python return render(request, "index.html", context) ``` ```python 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:** ```python 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` и дополнительно `_list`, например `post_list`; - `DetailView` — `object` и дополнительно ``, например `post`. Методы, которые часто переопределяют: - `get_queryset()` — изменить список объектов; - `get_object()` — изменить получение одного объекта; - `get_context_data()` — добавить данные в шаблон. При переопределении `get_context_data()` обычно сначала вызывают базовую логику: ```python 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` ищет `/_list.html`; - `DetailView` ищет `/_detail.html`. ```python # 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("/", 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-ошибку. ```html {% for post in posts %} {% empty %}

Постов нет.

{% endfor %} ``` ### Наследование шаблонов Позволяет избежать дублирования HTML-кода. - **Базовый шаблон (`base.html`):** Определяет блоки `{% block content %}{% endblock %}`. - **Дочерний шаблон:** Использует `{% extends "base.html" %}` и переопределяет блоки. ```html {% block title %}Сайт{% endblock %}
{% block content %}{% endblock %}
``` ```html {% extends "base.html" %} {% block title %}Посты{% endblock %} {% block content %}

Посты

{% for post in posts %} {{ post.title }} {% endfor %} {% endblock %} ``` --- ## Статические файлы (Static) - Подключаются через `{% load static %}`. - Настройки в `settings.py`: `STATIC_URL`, `STATICFILES_DIRS`. - В продакшне используется команда `python manage.py collectstatic`. Статика — это CSS, JavaScript, изображения и другие файлы, которые не генерируются view. ```python # settings.py STATIC_URL = "static/" STATICFILES_DIRS = [BASE_DIR / "static"] ``` ```html {% load static %} ``` ```bash python manage.py collectstatic ``` ## Простыми словами для экзамена FBV — view как функция. CBV — view как класс с готовой логикой. Маршрут соединяет URL и view: ```python path("find/", views.find, name="find") ``` В шаблоне ссылка на именованный маршрут создаётся так: ```html Поиск ``` Шаблонные переменные пишутся через `{{ variable }}`. Шаблонные теги пишутся через `{% tag %}`. Комментарии пишутся через `{# comment #}`. Ключ словаря в шаблоне читается через точку: ```django {{ user_data.name }} ```