Files
SecondBrain/90 Library/Programming/Python/Django: Представления, шаблоны и CBV.md
T
2026-05-31 10:13:47 +03:00

241 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: processing
type: concept
tags: [django, routing, templates, cbv, fbv]
created: 2026-05-30
updated: 2026-05-31
title: "Django: Представления, шаблоны и CBV"
source: ["[[lec2-django_lec_urls_views_templates-1.pdf]]", "[[lec3-django_cbv-1.pdf]]", "[[p4-django_cbv-1.pdf]]"]
---
# 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 в коде и шаблонах.
```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("<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"),
]
```
```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})
```
---
## Представления (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})
```
```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"
```
```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("<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`.
```html
{% 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" %}` и переопределяет блоки.
```html
<!-- templates/base.html -->
<!doctype html>
<html lang="ru">
<head>
<title>{% block title %}Сайт{% endblock %}</title>
</head>
<body>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
```
```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.
```python
# settings.py
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
```
```html
{% load static %}
<link rel="stylesheet" href="{% static 'css/app.css' %}">
<script src="{% static 'js/app.js' %}"></script>
```
```bash
python manage.py collectstatic
```