34
Since Django 1.9, as per the docs, it is possible to apply decorator in the next way:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required, name='dispatch')
class YourClassBasedView(TemplateView):
...
where name
is the name of the method to be decorated.
or in case of few decorators:
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator
decorators = [never_cache, login_required]
@method_decorator(decorators, name='dispatch')
class YourClassBasedView(TemplateView):
...
19
There is a very simple solution to achieve what you want, and it doesnโt implies decorating dispatch
method. You must use the method_decorator
over your methods (get/post) and pass the decorator call (not the decorator itself) as a parameter.
In your case it would be:
from django.utils.decorators import method_decorator
class ProfileView(View):
template_name = 'index.html'
# Return profile of any role (client/employee/admin)
@method_decorator(login_required())
def get(self, request, *args, **kwargs):
...
# Client sign up
# No decorator is needed
def post(self, request):
...
Note the parethesis in the login_required
decorator.
You can pass any function-oriented decorator, even a custom one. For instance:
def white_list_check():
def decorator(func):
def wrapper(request, *args, **kwargs):
ip = request.META.get('REMOTE_ADDR', '0.0.0.0')
if ip in WHITE_LIST:
return func(request, *args, **kwargs)
else:
return HttpResponseForbidden()
return wrapper
return decorator
And then, again:
class YourView(View):
@method_decorator(white_list_check())
def get(self, request):
...
- [Django]-Django: Example of generic relations using the contenttypes framework?
- [Django]-ForeignKey to abstract class (generic relations)
- [Django]-Troubleshooting Site Slowness on a Nginx + Gunicorn + Django Stack
6
Some decorators like never_cache can be used in the urls.py in stead of the old way: in views.py
e.g. the never_cache decorator:
in the old style views.py:
from django.views.decorators.cache import never_cache
@never_cache
def oldstyle_view(request):
# and so on
when using class based views, in urls.py:
from django.views.decorators.cache import never_cache
urlpatterns = patterns('',
(r'someurl/^$', never_cache(SomeClassBasedView.as_view())),
)
Edit 1st aug 2015
Note: this can be handy for those views where you do not have a complete view defined in views.py, otherwhise the decorator can be applied to the depatch method in the view as well.
- [Django]-Django-Forms with json fields
- [Django]-Django โ Website Home Page
- [Django]-Add rich text format functionality to django TextField
5
You can override dispatch
method and call different decorators based on type of request:
from django.utils.decorators import method_decorator
class ProfileView(View):
...
def dispatch(self, *args, **kwargs):
dispatch_method = super(ProfileView, self).dispatch
if self.request.method == 'GET':
dispatch_method = method_decorator(my_get_decorator)(dispatch_method)
elif self.request.method == 'POST':
dispatch_method = method_decorator(my_post_decorator)(dispatch_method)
return dispatch_method(*args, **kwargs)
- [Django]-Django index page best/most common practice
- [Django]-Django: Example of generic relations using the contenttypes framework?
- [Django]-Remove Labels in a Django Crispy Forms
4
You need to apply the decorator to the dispatch method of the class based view. This can be done as follows:
class ProfileView(View):
@youdecorator
def dispatch(self,request,*args,**kwargs):
return super(ProfileView,self).dispatch(request,*args,**kwargs)
//Rest of your code.
- [Django]-Add inline model to django admin site
- [Django]-How to get username from Django Rest Framework JWT token
- [Django]-Sending post data from angularjs to django as JSON and not as raw content