一、简介
本篇文章主要是通过一个实际的案例来介绍drf的权限组件如何使用
二、代码
在认证组件的基础上补充代码,具体想要实现总监,经理,职员三种不同的角色的权限划分,因此在权限组件里定义了三个不同的类,代码如下:
# ext/per.py
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import PermissionDenied
import random
class UserPermission(BasePermission):
message = {"code": 203, "data": "你没有员工的权限"}
def has_permission(self, request, view):
if request.user.role == 3:
return True
return False
class ManagerPermission(BasePermission):
message = {"code": 203, "data": "你没有经理的权限"}
def has_permission(self, request, view):
if request.user.role == 2:
return True
"""
这里我是想如果不修改权限组件的“与”关系,是否能实现经理和职员都可访问同一个api
虽然加一个elif可以实现,但是会导致如果只想经理能访问的api,职员都能访问了
故放弃,因此将权限组件的“与”关系修改为或关系还是有必要的
"""
# elif request.user.role == 3:
# return True
return False
class AcePermission(BasePermission):
message = {"code": 203, "data": "你没有总监的权限"}
def has_permission(self, request, view):
if request.user.role == 1:
return True
return False
在模型类中添加role角色,代码如下:
# api/models.py
from django.db import models
class UserInfo(models.Model):
# 新增
role = models.IntegerField(verbose_name='角色', choices=((1, '总监'), (2, '经理'), (3, '职员')),default=3)
username = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=64)
# 临时方式、jwt
token = models.CharField(verbose_name='TOKEN', max_length=64, null=True, blank=True)
views中的代码将Order类的权限组件关系修改为了“或”,并且指定只能总监和经理才能访问,职员没有权限访问Order类,代码如下:
import uuid
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from ext.per import AcePermission, UserPermission, ManagerPermission
from api import models
class UserView(APIView):
def get(self, request):
print(request.user)
print(request.auth)
return Response("UserView")
class LoginView(APIView):
authentication_classes = []
permission_classes = []
def post(self, request):
# 1.接受用户名和密码
print(request.data)
user = request.data.get('username')
pwd = request.data.get('password')
# 2.数据库校验
user_object = models.UserInfo.objects.filter(username=user, password=pwd).first()
if not user_object:
return Response({'code': 201, "msg": "用户名密码错误"})
token = str(uuid.uuid4())
user_object.token = token
user_object.save()
return Response({'code': 0, 'data': token})
class OrderView(APIView):
# 只能总监和经理才能访问该接口
permission_classes = [ManagerPermission, AcePermission, ]
# 将权限组件的关系修改为“或”
def check_permissions(self, request):
for permission in self.get_permissions():
if permission.has_permission(request, self):
return
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
def get(self, request):
return Response({'code': 0, 'data': ['番茄炒蛋', '鸡米芽菜']})
三、测试接口
访问order接口
修改为职员也能访问,代码修改如下(仅展示Order类):
class OrderView(APIView):
# 只需要注释掉下面这一行,让dispatch读取permission_classes时
# 去settings.py中读取,在settings.py中已将三个权限全部加入
# permission_classes = [ManagerPermission, AcePermission, ]
def check_permissions(self, request):
for permission in self.get_permissions():
if permission.has_permission(request, self):
return
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
def get(self, request):
return Response({'code': 0, 'data': ['番茄炒蛋', '鸡米芽菜']})
访问order接口