Django has two kinds of views: function-based views and class-based views. The role of a view is mainly to fill in logic and return a response body. Function-based views are hard to extend and have a low rate of code reuse. Class-based views, on the other hand, can use inheritance and mixins to reuse and extend functionality quickly. This article mainly discusses how Django processes class-based views and how class-based view decorators are implemented.
1. Django’s Views
Django’s URL resolver passes an HttpRequest object and the corresponding arguments to a callable function, and expects it to return an HttpResponse object. That callable function is the view function.
1.1 Function-Based Views
views.py
| |
urls.py
| |
Function-based views (FBV) are only used for custom error handling, or in situations where implementing things with class-based views would be very complex.
1.2 Class-Based Views
views.py
| |
urls.py
| |
To decouple views from URLs and to reuse code, Django provides class-based views.
A class-based view (CBV) provides an as_view() static method. Calling that method creates an instance of the class. It then calls the instance’s dispatch() method, and dispatch() calls the like-named method on the instance according to the type of the request. If no matching method is found, it raises an HttpResponseNotAllowed exception.
The series of class-based view classes Django provides all inherit from a single base class, View (django.views.generic.base.View). This base class implements the interface to URLs (as_view), request method matching (dispatch), and some other basic functionality. For example, RedirectView implements HTTP redirection, and TemplateView adds a method for rendering templates.
The as_view and dispatch methods of the View class in django.views.generic.base.py
| |
2. Django View Mixin Classes
Django abstracts and encapsulates the basic HTTP request and response into classes. In use, you only need to aggregate these base classes and override or directly reuse them in whatever way your requirements demand. These base classes are called mixins.
In the django.views.generic package, besides base, which provides the few most fundamental mixins for building a CBV plus the View base class for CBVs, there are four more modules,
- detail, for displaying detailed data: SingleObjectMixin, SingleObjectTemplateResponseMixin
- list, for displaying lists: MultipleObjectMixin, MultipleObjectTemplateResponseMixin
- edit, providing create and edit functionality: DeletionMixin, FormMixin
- dates, for displaying and retrieving year/month/day related data: YearMixin, MonthMixin, DayMixin, WeekMixin, DateMixin
A view class can inherit from multiple mixins, but can only inherit from one View (including its subclasses).
3. Class-Based View Decorators
3.1 Decorating dispatch
The dispatch decorator affects all method functions of the view class. Starting with Django 1.9, method_decorator supports a name argument, which lets you specify a method, for example name=‘get’ to decorate only the get function. If multiple decorators need to be configured, @method_decorator also accepts a list argument, so several decorators can be assembled at once.
| |
Usage of a decorator with arguments:
@method_decorator(login_required_by_role(‘super’))
3.2 Decorating the View Class
Decorating the class, like decorating dispatch, also affects all HTTP methods.
| |
3.3 Configuring Decorators in URLConf
| |
