Django study notes of Class Based View

  • 2020-05-26 09:27:48
  • OfStack

preface

Everyone knows that learning Django is so easy that it takes almost no effort to get started. Configure one url, assign one function to handle it, return response, and there's almost nothing hard to understand.

After writing too much, I gradually realized some problems. Let's say I have an view that's a little bit more complicated, and it calls a lot of other functions. What if you want to encapsulate these functions? Of course, you can use the comment #-- view-- to isolate the function, which is too low to be wrapped.

Python is an object-oriented programming language, and many of the object-oriented benefits (inheritance, encapsulation, polymorphism) would be missed if you were developing only functions. So Django later added Class-Based-View. Let's write View in class. There are two main advantages to doing this:

Improved code reusability by using object-oriented techniques such as Mixin (multiple inheritance) You can use different functions for different HTTP methods, rather than many if judgments, to improve code readability

Use the class - based views

If we were to write an view that deals with the GET method, it would look something like this.


from django.http import HttpResponse
 
def my_view(request):
 if request.method == 'GET':
  # <view logic>
  return HttpResponse('result')

If you write it in class-based view, it looks like this.


from django.http import HttpResponse
from django.views import View
 
class MyView(View):
 def get(self, request):
  # <view logic>
  return HttpResponse('result')

Django's url assigns one request to a callable function, not one class. To address this issue, class-based view provides one as_view() A static method (that is, a class method) that calls this method creates an instance of a class and then calls it through the instance dispatch() Method, dispatch() The method handles request (e.g get() , post() , etc.). So here, these methods are pretty much function-based view, so to receive request, you get 1 response back. If the method is not defined, an HttpResponseNotAllowed exception is thrown.

In url, it says:


# urls.py
from django.conf.urls import url
from myapp.views import MyView
 
urlpatterns = [
 url(r'^about/$', MyView.as_view()),
]

The properties of a class can be set in two ways. The first is the common Python method, which can be overridden by subclasses.


from django.http import HttpResponse
from django.views import View
 
class GreetingView(View):
 greeting = "Good Day"
 
 def get(self, request):
  return HttpResponse(self.greeting)
 
# You can override that in a subclass
 
class MorningGreetingView(GreetingView):
 greeting = "Morning to ya"

Second, you can also specify the class's properties in url:

Set the class property Python in url


urlpatterns = [
 url(r'^about/$', GreetingView.as_view(greeting="G'day")),
]

Using Mixin

I think the first thing to understand about django's class-based-view (hereinafter referred to as cbv) is what django introduced cbv for. Before django1.3, generic view, also known as the generic view, used function-based-view (fbv), which is a function-based view. Some people think fbv is more pythonic than cbv, but I don't think so. One of the most important features of python is that it is object-oriented. While cbv can better reflect the object orientation of python. cbv implements view methods through class. Compared with function, class makes better use of polymorphic specificity, so it is easier to abstract the more common functions within the project at a macro level. I won't say much about polymorphism, but those of you who are interested in it, Google. In short, it can be understood that one thing has multiple forms. The implementation principle of cbv is easy to understand by looking at the source code of django. After url is routed to this cbv, cbv internal dispatch method is distributed, get request is distributed to cbv.get method, post request is distributed to cbv.post method, other methods are similar. How do you take advantage of polymorphism? cbv introduces the concept of mixin. Mixin is a set of basic classes that are then combined into different Mixin classes to create the desired class.

So the basis of understanding cbv is understanding Mixin. Django USES Mixin to reuse code. One View Class can inherit multiple Mixin, but only one View (including a subclass of View). It is recommended to write View on the far right and multiple Mixin on the left. Mixin is also a relatively complex technology, which will not be discussed in detail in this article. Please write an article about Mixin in the future.

Use decorators

In CBV, you can use method_decorator to decorate methods.


from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
 
class ProtectedView(TemplateView):
 template_name = 'secret.html'
 
 @method_decorator(login_required)
 def dispatch(self, *args, **kwargs):
  return super(ProtectedView, self).dispatch(*args, **kwargs)

You can also write it on top of the class, passing in the name of the method.


@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
 template_name = 'secret.html'

If you have multiple decorators to decorate 1 method, you can write 1 list. For example, the following two ways of writing are equivalent.


decorators = [never_cache, login_required]
 
@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
 template_name = 'secret.html'
 
@method_decorator(never_cache, name='dispatch')
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
 template_name = 'secret.html'

conclusion

The above is the whole content of this article, I hope the content of this article to your study or work can bring 1 definite help, if you have questions you can leave a message to communicate.


Related articles: