[英]Django - How to use decorator in class-based view methods?
我正在用django 1.8開發一個網站。 這是其中一個視圖的示例:
class ProfileView(View):
template_name = 'index.html'
# Return profile of any role (client/employee/admin)
# Login required
def get(self, request, *args, **kwargs):
try:
profile = Profile.objects.get(user=request.user)
agency = None
if request.user.is_employee():
employee = EmployeeProfile.objects.get(profile=profile)
agency = employee.agency
if request.user.is_manager():
agency = Agency.objects.get(manager=request.user)
except (Profile.DoesNotExist, EmployeeProfile.DoesNotExist, Agency.DoesNotExist) as e:
return HttpResponseRedirect('/404')
return render(request, self.template_name, {"profile": profile, "agency": agency})
# Client sign up
# No decorator is needed
def post(self, request):
sign_up = SignUpForm(request.POST, request.FILES)
response = json.loads(utils.create_user(sign_up,request.POST['avatar']))
if response['profile'] is None:
return JsonResponse({"code": 400, "response": response['message']})
profile = serializers.deserialize("json", response['profile']).next().object
group = Group.objects.get(name='clients')
profile.user.groups.add(group)
return HttpResponseRedirect('/')
問題是,根據對控制器(視圖)的請求類型,我可以有不同的裝飾器嗎?
從Django 1.9開始, 根據文檔 ,可以在下一個方式應用裝飾器:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required, name='dispatch')
class YourClassBasedView(TemplateView):
...
其中name
是要裝飾的方法的名稱。
或者在少數裝飾者的情況下:
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):
...
您需要將裝飾器應用於基於類的視圖的dispatch方法。 這可以按如下方式完成:
class ProfileView(View):
@youdecorator
def dispatch(self,request,*args,**kwargs):
return super(ProfileView,self).dispatch(request,*args,**kwargs)
//Rest of your code.
有一個非常簡單的解決方案來實現您想要的,它並不意味着裝飾dispatch
方法。 您必須對方法(get / post)使用method_decorator
並將裝飾器調用 (不是裝飾器本身)作為參數傳遞。
在你的情況下,它將是:
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):
...
請注意login_required
裝飾器中的parethesis。
您可以傳遞任何面向函數的裝飾器,甚至是自定義裝飾器。 例如:
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
然后,再次:
class YourView(View):
@method_decorator(white_list_check())
def get(self, request):
...
像never_cache這樣的裝飾器可以在urls.py中使用而不是舊的方式:在views.py中
例如,never_cache裝飾器:
在舊式的views.py中:
from django.views.decorators.cache import never_cache
@never_cache
def oldstyle_view(request):
# and so on
在urls.py中使用基於類的視圖時:
from django.views.decorators.cache import never_cache
urlpatterns = patterns('',
(r'someurl/^$', never_cache(SomeClassBasedView.as_view())),
)
編輯2015年8月1日
注意:對於那些沒有在views.py中定義完整視圖的視圖,這可以很方便,除此之外,裝飾器也可以應用於視圖中的depatch方法。
您可以覆蓋dispatch
方法並根據請求類型調用不同的裝飾器:
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.