(django) 11 class views

Keywords: Python Django

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.

Posted by peachsnapple on Sat, 19 Jan 2019 08:48:12 -0800