Функциональные views (FBV)
View — сердце приложения. Это функция, которая принимает request и возвращает response. С неё начинается вся логика, которую видит пользователь.
Суть: функциональная view (FBV) — это обычная Python-функция, принимающая request первым аргументом и возвращающая HttpResponse. Помощники render, redirect и get_object_or_404 упрощают типовые задачи.
Простейшая view
Функциональная view (Function-Based View, FBV) — самый прямой способ обработать запрос. Это функция, первый аргумент которой — request, а возвращает она HttpResponse:
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
def post_list(request):
posts = Post.objects.filter(is_published=True)
return render(request, "blog/post_list.html", {"posts": posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, "blog/post_detail.html", {"post": post})
Три помощника, которые вы будете использовать постоянно
render(request, template, context) — загружает шаблон, подставляет данные из словаря context и возвращает готовый HTML-ответ. Это самый частый паттерн. get_object_or_404(Model, **kwargs) — пытается достать объект, а если его нет — отдаёт страницу 404 вместо падения с ошибкой. redirect(...) — отправляет браузер на другой URL (например, после успешной отправки формы).
Обработка GET и POST в одной view
Часто одна view обслуживает и показ формы (GET), и её обработку (POST). Тогда внутри view ветвимся по методу:
def create_post(request):
if request.method == "POST":
title = request.POST.get("title")
Post.objects.create(title=title)
return redirect("post_list")
return render(request, "blog/create.html")
GET показывает пустую форму, POST создаёт запись и делает редирект. Паттерн «POST → redirect → GET» защищает от повторной отправки формы при обновлении страницы.
Как это работает под капотом
View — это маршрутизация плюс выбор действия по методу. По сути, это таблица «метод → функция-обработчик». Эту диспетчеризацию легко смоделировать на чистом Python — именно так Django решает, что делать с запросом:
# Попробуй сам ▶ — диспетчер методов как во view
def handle_get(data):
return f"200 OK: показываю {len(data)} записей"
def handle_post(data):
data.append({"title": "Новый пост"})
return f"302 Redirect: создано, теперь {len(data)} записей"
def view(method, data):
handlers = {"GET": handle_get, "POST": handle_post}
handler = handlers.get(method)
if handler is None:
return "405 Method Not Allowed"
return handler(data)
posts = [{"title": "Первый"}, {"title": "Второй"}]
print("GET :", view("GET", posts))
print("POST:", view("POST", posts))
print("GET :", view("GET", posts))
print("PUT :", view("PUT", posts))
Django делает ровно это: смотрит на request.method и направляет запрос в нужную ветку, а на неподдержанный метод отвечает 405.
Возврат JSON и другие типы ответов
Не все ответы — это HTML. Для API возвращают JSON через JsonResponse: return JsonResponse({"status": "ok", "count": 5}). Это основа для собственных эндпоинтов, хотя для серьёзных API используют Django REST Framework — о нём в последнем разделе. Кроме того, view может вернуть редирект (HttpResponseRedirect или удобный redirect), ошибку (HttpResponseNotFound, HttpResponseForbidden) или файл (FileResponse для отдачи документов и потоковой передачи больших файлов). Главное помнить: что бы вы ни возвращали, это всегда наследник HttpResponse с правильным кодом статуса и заголовками.
Декораторы view
Поведение view часто настраивают декораторами — обёртками, которые добавляют логику до и после вызова. Самые полезные: @require_http_methods(["GET", "POST"]) ограничивает допустимые методы (на остальные вернётся 405), @login_required закрывает страницу от анонимов, @cache_page(60) кеширует ответ на заданное время. Декораторы — чистый и переиспользуемый способ навесить общее поведение, не загромождая тело самой view проверками.
Частые ошибки
- Забыть вернуть HttpResponse. Если функция ничего не возвращает — ошибка.
- Не обработать отсутствие объекта. Используйте
get_object_or_404, а не голыйget(). - Не делать redirect после POST. Обновление страницы повторит отправку формы.
- Складывать всю логику в одну толстую view. Выносите её в модели и сервисы.
Best practices
- Держите views тонкими: они оркестрируют, а не содержат бизнес-логику.
- Всегда применяйте паттерн «POST → redirect → GET» для форм.
- Используйте
get_object_or_404для корректных 404 вместо 500. - Передавайте данные в шаблон через явный словарь context.
Итоги
Функциональная view — это функция request → response. Помощники render, redirect и get_object_or_404 покрывают большинство задач. Ветвление по request.method позволяет одной view показывать и обрабатывать формы. Дальше посмотрим, как Django умеет генерировать типовые views за нас — через классы.