← Назад к вопросам

Какие базовые view-классы есть в Django?

2.0 Middle🔥 161 комментариев
#Брокеры сообщений

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Базовые View-классы в Django

Джанго предоставляет несколько базовых view-классов (CBV — Class-Based Views) для быстрого создания представлений. Они экономят код и обеспечивают лучшую организацию логики.

1. View (Базовый класс)

Это самый простой и базовый класс для всех view-классов:

from django.views import View
from django.http import HttpResponse

class MyView(View):
    def get(self, request):
        return HttpResponse("Hello, GET!")
    
    def post(self, request):
        return HttpResponse("Hello, POST!")

# urls.py
path('my/', MyView.as_view())

Методы соответствуют HTTP методам: get(), post(), put(), delete(), patch().

2. TemplateView (для шаблонов)

Отображает шаблон без получения данных из БД:

from django.views.generic import TemplateView

class HomeView(TemplateView):
    template_name = 'home.html'
    
    # Опционально добавить контекст
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Home Page'
        return context

# urls.py
path('', HomeView.as_view(), name='home')

# template: home.html
# <h1>{{ title }}</h1>

3. ListView (для списков объектов)

Для отображения списка объектов из БД с пагинацией:

from django.views.generic import ListView
from .models import Article

class ArticleListView(ListView):
    model = Article  # Модель, из которой получаем данные
    template_name = 'article_list.html'  # Шаблон (опционально)
    context_object_name = 'articles'  # Имя переменной в шаблоне
    paginate_by = 10  # Элементов на странице
    
    # Фильтрация
    def get_queryset(self):
        return Article.objects.filter(published=True).order_by('-created_at')

# template: article_list.html
# {% for article in articles %}
#   <h2>{{ article.title }}</h2>
# {% endfor %}
# 
# {% if is_paginated %}
#   <a href="?page={{ page_obj.next_page_number }}">Next</a>
# {% endif %}

4. DetailView (для одного объекта)

Для отображения информации об одном объекте:

from django.views.generic import DetailView
from .models import Article

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'article_detail.html'  # Опционально
    context_object_name = 'article'  # Имя в шаблоне
    
    # Получение pk или slug из URL
    # URL может быть: /article/<int:pk>/ или /article/<slug:slug>/

# urls.py
path('article/<int:pk>/', ArticleDetailView.as_view(), name='article-detail')
path('article/<slug:slug>/', ArticleDetailView.as_view(), name='article-detail')

# template: article_detail.html
# <h1>{{ article.title }}</h1>
# <p>{{ article.content }}</p>

5. CreateView (для создания объектов)

Для создания новых объектов с автоматической обработкой формы:

from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import Article
from .forms import ArticleForm

class ArticleCreateView(CreateView):
    model = Article
    form_class = ArticleForm
    template_name = 'article_form.html'  # Автоматическое имя
    success_url = reverse_lazy('article-list')  # Куда редирект после создания
    
    # Заполнить поле перед сохранением
    def form_valid(self, form):
        form.instance.author = self.request.user  # Установить автора
        return super().form_valid(form)

# urls.py
path('create/', ArticleCreateView.as_view(), name='article-create')

# template: article_form.html
# <form method="post">
#   {% csrf_token %}
#   {{ form.as_p }}
#   <button type="submit">Create</button>
# </form>

6. UpdateView (для обновления объектов)

Для редактирования существующих объектов:

from django.views.generic import UpdateView
from django.urls import reverse_lazy
from .models import Article
from .forms import ArticleForm

class ArticleUpdateView(UpdateView):
    model = Article
    form_class = ArticleForm
    template_name = 'article_form.html'
    success_url = reverse_lazy('article-list')
    
    # Проверка прав доступа
    def test_func(self):
        article = self.get_object()
        return article.author == self.request.user

# urls.py
path('article/<int:pk>/edit/', ArticleUpdateView.as_view(), name='article-edit')

7. DeleteView (для удаления объектов)

Для удаления объектов с подтверждением:

from django.views.generic import DeleteView
from django.urls import reverse_lazy
from .models import Article

class ArticleDeleteView(DeleteView):
    model = Article
    template_name = 'article_confirm_delete.html'  # Страница подтверждения
    success_url = reverse_lazy('article-list')

# urls.py
path('article/<int:pk>/delete/', ArticleDeleteView.as_view(), name='article-delete')

# template: article_confirm_delete.html
# <p>Are you sure to delete: {{ article.title }}?</p>
# <form method="post">
#   {% csrf_token %}
#   <button type="submit">Delete</button>
# </form>

8. FormView (для произвольных форм)

Для работы с формами, не привязанными к модели:

from django.views.generic import FormView
from django import forms
from django.urls import reverse_lazy

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

class ContactFormView(FormView):
    form_class = ContactForm
    template_name = 'contact_form.html'
    success_url = reverse_lazy('home')
    
    def form_valid(self, form):
        # Обработка валидной формы
        send_email(form.cleaned_data['email'])
        return super().form_valid(form)

# urls.py
path('contact/', ContactFormView.as_view(), name='contact')

9. RedirectView (для редиректов)

Для редиректов на другие страницы:

from django.views.generic import RedirectView

class OldPageRedirectView(RedirectView):
    url = '/new-page/'  # Статический URL
    permanent = True  # HTTP 301 (постоянный) вместо 302 (временный)

# Или динамический URL
class ArticleRedirectView(RedirectView):
    permanent = True
    
    def get_redirect_url(self, *args, **kwargs):
        article = Article.objects.get(pk=kwargs['pk'])
        return article.get_absolute_url()

# urls.py
path('old/', OldPageRedirectView.as_view())
path('article/<int:pk>/redirect/', ArticleRedirectView.as_view())

Миксины для управления доступом

Джанго предоставляет миксины для проверки прав доступа:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import UpdateView

class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Article
    form_class = ArticleForm
    success_url = reverse_lazy('article-list')
    
    # Проверить, что это автор статьи
    def test_func(self):
        article = self.get_object()
        return article.author == self.request.user
    
    # Где редиректить если не авторизован
    login_url = 'login'

Сравнение FBV vs CBV

# Function-Based View (FBV)
def article_list(request):
    articles = Article.objects.all()
    return render(request, 'article_list.html', {'articles': articles})

# Class-Based View (CBV) — компактнее
class ArticleListView(ListView):
    model = Article

Вывод

  • View — базовый класс для всех видов
  • TemplateView — просто отобразить шаблон
  • ListView — список объектов
  • DetailView — один объект
  • CreateView — создание объекта
  • UpdateView — редактирование объекта
  • DeleteView — удаление объекта
  • FormView — произвольная форма
  • RedirectView — редирект

CBV-классы экономят код и обеспечивают консистентность