Catalog
The view defined by function mode is called function view. Although it is convenient to use and easy to understand, when a s view has multiple request modes, it is necessary to use branches to write logic corresponding to different request modes.
Using the function view, the code looks like this
def my_view(request): if request.method == 'GET': return HttpResponse("get") if request.method == 'POST': return HttpResponse("post")
1. Use Class View
The core of class-based views is to allow you to respond to different HTTP request methods with different instance methods, rather than using conditional branching code in a view function.
Create Class View
Using the class view, the code looks like this
from django.views import View class ClassView(View): def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Class views need to inherit the View class provided by Django and import from django.views import View
Registration routing
When configuring class views, use the as_view method of class views to register routes
urlpatterns = [ url(r'^class_view', views.ClassView.as_view(), name="class_view") ]
as_view returns a reference to a method in the class. It goes to View and executes the dispatch method. The dispatch method finds a class method like GET POST in the class, matches the request method, and returns a reference to the method.
If a GET request is sent to the class view above, it converts the GET to lowercase and matches the method in the class, then matches the get method, and returns the reference to the get method to the as_view call. So the last as_view under the get request is a reference to the get method.
Class View Using Decorator
Decorators can be used to add functionality to class views. There are three ways to use decorators.
- Decorate in url configuration
- Decorate in Class View
- Using Mixin Extension Class
For ease of understanding, use the following case to demonstrate
def decorator(func): def wrapper(request, *args, **kwargs): print('Decorator called') return func(request, *args, **kwargs) return wrapper class ClassView(View): def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Decorate in url
url(r'^class_view', views.decorator(views.ClassView.as_view()), name="class_view")
Send GET or POST type requests to print results
Decorator called
Call the function in the url and pass in the as_view method, which decorates all the requested functions.
This method puts decoration in the url configuration, which is not conducive to the integrity and readability of the code, so it is not used in general.
Decorate in Class View
Decorator can not be directly decorated in class view. method_decorator is needed to convert the decorator bits to the class decorator.
In the decorator we wrote, the inner function receives the parameter request
def decorator(func): def wrapper(request, *args, **kwargs): print('Decorator called') return func(request, *args, **kwargs) return wrapper
In the class view method, the first parameter is self, so use method_decorator to add the first parameter of the decorator to self to use the method in the class view.
You can also manually add a parameter self to the decorator
def decorator(func): def wrapper(self, request, *args, **kwargs): print('Decorator called') return func(self, request, *args, **kwargs) return wrapper
Decorate all methods
The dispatch method of the class can be overridden and decorated with the following code
class ClassView(View): @method_decorator(decorator) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Requests using GET or POST will execute the decorator and print the results.
Decorator called
Decorate only one method
class ClassView(View): @method_decorator(decorator) def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Only when requests are made in GET mode will the decorator be executed and the results printed.
Decorator called
POST mode does not execute decorators.
name parameter of method_decorator
Full Decoration Method
@method_decorator(decorator, name="dispatch") class ClassView(View): def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Specify the method to be decorated
@method_decorator(decorator, name="get") class ClassView(View): def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
Using Mixin Extension Class
Extension classes use Python's multi-inherited MRO features.
class MyMixin(object): @classmethod def as_view(cls, *args, **kwargs): view = super().as_view(*args, **kwargs) view = decorator(view) return view class ClassView(MyMixin, View): def get(self, request): return HttpResponse("get") def post(self, request): return HttpResponse("post")
This way decorates all methods, and you can use this way to add multiple decorators to the method.