• Информация на сайте предоставляется «как есть», может содержать неточности и не является консультацией или офертой.
  • Перед использованием проконсультируйтесь со специалистом.

Используя сайт, вы подтверждаете, что вы изучили и согласны с документами Политика конфиденциальности и обработки персональных данныхи Пользовательское соглашение.

Сайт использует cookies для работы и сбора аналитики. Вы можете принять или настроить их, а также полностью отключить в настройках браузера.

Настройки cookies
Необходимые для работы веб-сайта

Используются для входа, навигации и защиты (например: sessionid, csrftoken). Без них сайт может работать с перебоями.

Помогают улучшить сайт, собирая статистику посещений (например, через Яндекс Метрику).

Используются для показа персонализированной рекламы и ретаргетинга в рекламных сетях.

Настройки интерфейса

Декоративный эффект свечения при клике по странице.

DEV -
PROGRAM.RU
Контакты

Django CBV: готовые классы на примере Generic Base View

Смотрим CBV под капотом и как подключать классы к URL-маршрутам, за что отвечают методы setup() и dispatch() и как использовать Generic Views

В статье Django CBV: что такое Class-Based Views мы разобрались в каких случаях полезно использовать CBV, теперь же посмотрим что для нас приготовили разработчики Django, чтобы облегчить написание кода.

В Django имеется целая серия готовых типов классов views - представлений, для удобства они собраны на сайте https://ccbv.co.uk/ .

Что под капотом у CBV

Все начинается с обычного Python класса с парой хитростей - View .

Этот базовый класс простой и универсальный, его фишка в том, что он содержит методы (функции), которые далее по цепочке наследуют другие готовые классы.

Его единственное предназначение это принять запрос и вернуть ответ, а так же если указано, он перенаправит запрос на необходимый метод (GET, POST, PUT, DELETE).

plaintext
URL-диспетчер        ← вызывает функцию из as_view()
      ↓
  as_view()          ← создаёт экземпляр класса - каждый запрос новый объект
      ↓
  setup()            ← устанавливает request, args, kwargs
      ↓
  dispatch()         ← смотрит на request.method
      ↓
  get() / post()     ← вызывает нужный метод
  / put() / delete()
      ↓
  HttpResponse       ← возвращает ответ

схема работы View класса

Как работать с urls у django CBV

В urls.py django вызывает функции, а не классы, потому требуется прописывать название класса с методом .as_view() .

Этот метод для каждого вызова создаёт новый экземпляр класса и возвращает функцию view.

path("about/", AboutView.as_view(), name="about")

пример пути django в файле urls.py у CBV

Что делает setup в CBV django

Setup записывает данные запроса в экземпляр объекта, чтобы они были доступны через self в любом методе класса.

    def setup(self, request, *args, **kwargs):

        if hasattr(self, "get") and not hasattr(self, "head"):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs

Метод setup класса View из кода Django

Метод можно переопределить, чтобы записать свои данные внутрь, которые будут использованы в dispatch или далее.

class ProjectView(View):
    def setup(self, request, *args, **kwargs):
        super().setup(request, *args, **kwargs) # чтобы сохранить изначальные request, args и kwargs
        self.project = get_object_or_404(Project, slug=kwargs["slug"])

Пример переопределения setup в django CBV

Что делает dispatch в CBV django

Dispatch это диспетчер, он по условию передает запрос дальше или останавливает его, в частности отдает 405 ошибку если одно из этих условий отрицательно:

  • метод указан в http_method_names

  • в классе присутствует метод из запроса (пример: get, post, put, delete, options, head)

python
class NoteView(View):
    http_method_names = ["get", "post"]  # остальное: 405

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({"error": "Требуется вход"}, status=401)
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return JsonResponse({"user": request.user.username})

    def post(self, request, *args, **kwargs):
        return JsonResponse({"ok": True}, status=201)

пример с http_method_names и dispatch в Django CBV

В примере выше запросы кроме get и post выдадут 405 ошибку.

Для чего полезен dispatch в Django CBV

Методом dispatch можно проверить права доступа до обращения к данным в представлении - view, это может сыграть важную роль в безопасности, в чистоте кода и в экономии ресурсов машины.

class OwnerOnlyMixin:
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect("login")
        return super().dispatch(request, *args, **kwargs)

пример кода проверки прав доступа через mixin с dispatch в django CBV

Также методом dispatch можно описать логику до и после обработки представления.

def dispatch(self, request, *args, **kwargs):
    start = time.monotonic()
    response = super().dispatch(request, *args, **kwargs)
    response["X-Elapsed"] = f"{time.monotonic() - start:.3f}"
    return response

пример кода dispatch в django CBV для подсчета затраченного времени

При помощи dispatch можно перенаправить запрос на иной обработчик по условию или пропустить дальше.

def dispatch(self, request, *args, **kwargs):
    if request.headers.get("X-Requested-With") == "XMLHttpRequest":
        return self.ajax(request, *args, **kwargs)
    return super().dispatch(request, *args, **kwargs)

пример кода dispatch в django cbv для перенаправления запроса

Generic Base Views: что это такое

Общие базовые представления (Generic Base View) это основные классы, которые зачастую являются основой для более сложных представлений (views).

В их число входят классы View (рассмотренный выше), TemplateView и RedirectView.

Многие дочерние представления - View обретают свою уникальность благодаря миксинам, напримерclass TemplateView(TemplateResponseMixin, ContextMixin, View).

Миксины пишутся с левой стороны от основного класса, так как обработка происходит слева направо.

Базовый класс TemplateView

TemplateView предназначен для страниц, которым нужно просто отобразить шаблон, подходит например для страницы "О нас", где просто текст.

Но по необходимости, можно вывести и данные через метод get_context_data(), а так же можно передать параметр через ссылку (url).

python
# views.py
class PageView(TemplateView):
    template_name = "pages/page.html" # достаточно этой строки

    def get_context_data(self, **kwargs):
    # добавляем если хочется встроить свои данные 
    # или обработать параметр из ссылки

        context = super().get_context_data(**kwargs)
        page = get_object_or_404(Page, slug=kwargs["slug"])
        context["page"] = page
        context["title"] = page.title
        context["posts"] = Post.objects.all()
        return context


# urls.py
path("pages/<slug:slug>/", PageView.as_view(), name="page")

# pages/page.html
<h1>{{ title }}</h1>
{{ page.content }}

{% for post in posts %}
  <p>{{ post.title }}</p>
{% endfor %}

пример TemplateView с get_context_data в Django CBV

Для простых страниц типа "О нас" или "Контакты" где не требуются данные из базы данных, а шаблон уже готов, можно использовать одностроковую версию сразу в urls.py.

path("about/", TemplateView.as_view(template_name="about.html"), name="about")

одностроковое использование TemplateView в Django CBV

Базовый класс RedirectView

RedirectView используется для перенаправления запроса пользователя.

# views.py
class OldPageView(RedirectView):
    url = "https://new-site.com"

# urls.py
urlpatterns = [
    path("old-page/", OldPageView.as_view(), name="old-page"),
]

Пример RedirectView в Django CBV

Возможно использовать и вариант в 1 строку.

path("blog/<int:pk>/", RedirectView.as_view(url="/posts/%(pk)d/"))

Пример в одну строку RedirectView в Django CBV

Если у вас остались вопросы по django базовым классовым представлениям View можете обратиться за консультацией к программисту.

Вам может быть интересно

Поделиться
Ничего не найдено
Найдите нужную страницу

Статьи, инструменты и помощь