django restframework框架三 權限
@(python之路)[django restframework框架二 權限]
django restframework框架二 權限
權限組件
我們一般將權限級別放到數據庫中,這樣也方便管理。
app01.urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'salary/$', views.SalaryView.as_view()),
]
model.py
from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
user_type_choices = (
(1,"員工"),
(2,"主管"),
)
user_type = models.IntegerField(choices=user_type_choices,default=1)
我們寫兩個視圖,如果權限大于0,就允許訪問;
如果權限大于一在可以訪問這個視圖;
from rest_framework.views import APIView
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
class MyPermission(object):
def has_permission(self,request,view):
return True
class SalaryView(APIView):
permission_classes = [MyPermission,]
def get(self,request,*args,**kwargs):
self.dispatch
return HttpResponse("get from SalaryView")
# usertype>1
class UserView(APIView):
permission_classes = [MyPermission,]
def get(self,request,*args,**kwargs):
return HttpResponse("get from UserView")
因為我們的 def has_permission(self,request,view):返回的時True。都有查看權限。如果返回的False的話,那么所有人都不能訪問。
我們可以在has_permission中拿到用戶相關的權限.
根據用戶權限,具體做判斷,根據權限不同,做不同的操作。
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
def has_permission(self,request,view):
user_type_id = request.auth.user.user_type
if user_type_id > 0:
return True
return False
class ManagerPermission(BasePermission):
def has_permission(self,request,view):
user_type_id = request.auth.user.user_type
if user_type_id > 1:
return True
return False
?一般我們的權限都是單獨寫出來的,一些基礎的權限會放在全局。單獨放一個文件就好。記得下視圖使用的時候要導入的。
補充:我們把要加權限的類寫法如下
class UserView(APIView):
permission_classes = [UserPermission,]
def get(self,request,*args,**kwargs):
self.dispatch
print(request.user)
print(request.auth)
return HttpResponse('user.get')
def post(self,request,*args,**kwargs):
return HttpResponse('user.post')
class SalaryView(APIView):
permission_classes = [UserPermission,ManagerPermission, ]
def get(self,request,*args,**kwargs):
return HttpResponse('...')
源碼分析
?我們還是從def dispatch()中的self.initial(request, *args, **kwargs)中入手
1
def initial(self, request, *args, **kwargs):
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# 版本處理
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# 處理認證
self.perform_authentication(request)
# 這里就是權限
self.check_permissions(request)
self.check_throttles(request)
2
?我們看一下self.check_permissions(request)做了什么;
def check_permissions(self, request):
# 循環每一個權限類實例化之后對象[per1,per2]
for permission in self.get_permissions():
# 當permission=False的時候,才會執行代碼中的
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
這里我么研究一下permission_denied
def permission_denied(self, request, message=None):
if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated()
raise exceptions.PermissionDenied(detail=message)
拋出異常,所以我們確定當permission=False時沒有權限的,反之有權限;
3
?注意:self.get_permissions()
def get_permissions(self):
return [permission() for permission in self.permission_classes]
?有種似曾相識的感覺。
class APIView(View):
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES原理都是一樣的。

浙公網安備 33010602011771號