权限类和认证类同样的逻辑,同样的方式,只是执行权限的方法名与执行认证的方法名不一样而已,名为has_permission
,并且需要将当前的视图类传递给该方法。
创建自定义权限类
自定义类位置:app.untils.permission.UserPermission
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| from rest_framework.permissions import BasePermission
class UserPermission(BaseException): message = '你没有该权限访问' def has_permission(self, request, view): if request.user.level>2: return True else: return None
|
视图类中指定接口判断权限
1 2 3 4 5 6 7 8 9 10 11 12
| from app.untils.permission import UserPermission
class BooksView(ModelViewSet): queryset = BookModel.objects.all() serializer_class = BookSerialize authentication_classes = [UserAuth] permission_classes = [UserPermission]
|
使用postman
测试改接口
测试接口地址:127.0.0.1:8000/books?token=008b3809097c42d4a0ba9bf94a5532e6
如果该token不正确,则认证类就直接先拦截下来了,根本走不到权限类。如果token值正确,且对应的用户level小于3,接口响应内容为
1 2 3
| { "detail": "你没有该权限访问" }
|
反之显示书籍列表
views.py所有代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| from django.http import JsonResponse
from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet
from app.models import User as UserModel from app.models import UserToken as UserTokenModel from app.models import Book as BookModel from app.untils import get_token
from app.api_serialize import BookSerialize
from app.untils.authentication import UserAuth
from app.untils.permission import UserPermission
class UserView(APIView): def post(self, request): response = dict() recev_data = {'username', 'password'} if recev_data.issubset(set(request.data)): userInfo = dict() for item in recev_data: userInfo[item] = request.data.get(item) user_obj = UserModel.objects.filter(**userInfo).first() if user_obj: access_token = get_token.generater_token() UserTokenModel.objects.update_or_create(user=user_obj, defaults={ 'token':access_token }) response['status_code'] = 200 response['status_message'] = '恭喜你,登录成功' response['access_token'] = access_token response['user_role'] = user_obj.get_level_display() else: response['status_code'] = 201 response['status_message'] = '用户名或密码错误' return JsonResponse(response)
class BooksView(ModelViewSet): queryset = BookModel.objects.all() serializer_class = BookSerialize authentication_classes = [UserAuth] permission_classes = [UserPermission]
|