django How to Use the Decorator through Class View

  • 2021-07-26 08:11:25
  • OfStack

Requirements: When we want to prohibit ip blacklist from accessing some of our pages, such as the registration page. How should it be operated?

Solution: At this time, we can design a decorator to filter ip blacklist.

The decorator is written as follows:


from functools import wraps


def ban_ip(func):
 @wraps(func)
 def wrapper(request,*args,**kwargs):
 IP = request.META.get("REMOTE_ADDR")
 if IP in ["127.0.0.1"]: #  You can add ip Blacklist to list 
  return HttpResponse(" Prohibit access ")
 return func
 return wrapper

If it is not a class view, you can use:


@ban_ip
def get_register(request):
 return render(request," Registration page .html")


def post_resiger(request):
 name = request.POST.get("name")
 password = request.POST.get("password")
 print(name)
 print(password)
 return HttpResponse(" Successful registration ")

In this way, one effect can be achieved. If ip is on the blacklist, "No Access" will pop up when accessing the registration page.

Requirements: However, the problem is that when we use class view, we have an self parameter when we define the view function. Because the decorator did not pass this parameter, it will report an error. What should I do?

Solution:

(1) Give specific methods in class view


class register(View):
 @method_decorator(ban_ip)
 def get(self,request):
 return render(request," Registration page .html")

 def post(self,request):
 name = request.POST.get("name")
 password = request.POST.get("password")
 print(name)
 print(password)
 return HttpResponse(" Successful registration ")

Interpretation:

Note: Decorators for function definitions cannot be applied directly to methods in class view because 1 self parameter is missing Resolution: You can use the method_decorator decorator to add the first self parameter to the function decorator so that it can be applied to the method of the class.

(2) Apply decorators to all methods of all class views

The class view is implemented through the method as_view () to distribute different requests. We can use this to apply decorators to all methods of class view.

A relatively simple but not practical method is in the project of urls. py above to achieve. Prefix the distribution request with a decorator.


url(r'^register$',ban_ip(views.register.as_view()))

Although this is convenient, it is too unsightly. The elegance of the decorator has been destroyed by it, so what should we do?

Solution: Rewrite the method of as_view () by 1 and add decorator function to it.


class register(View):
 
 #  Override the request distribution method, as_view() Core statement of 
 @method_decorator(ban_ip)
 def dispatch(self, request, *args, **kwargs):
 return super().dispatch(request, *args, **kwargs)

 def get(self,request):
 return render(request," Registration page .html")

 def post(self,request):
 name = request.POST.get("name")
 password = request.POST.get("password")
 print(name)
 print(password)
 return HttpResponse(" Successful registration ")

(3) Apply a decorator to a method in the class view


@method_decorator(ban_ip,name='get')
class register(View):

 def get(self,request):
 return render(request,"post.html")

 def post(self,request):
 title = request.POST.get("title")
 content = request.POST.get("content")
 print(title)
 print(content)
 return HttpResponse(" Published successfully ")

Related articles: