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
原理都是一样的。