一:权限组件的作用
不同的用户使用的功能是不同的,例如管理员和用户,我们可以对登录的用户进行权限的认证,来判断这个用户能不能使用这个功能。当然权限认证的前提是已经用户认证了,因此需要在最后一个用户认证类中返回认证成功的用户。
.models.py
from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=16) pwd = models.CharField(max_length=16) choice = ((1,"普通用户"),(2,"超级用户"),(3,"vip")) type = models.CharField(choices=choice,max_length=32,null=True) class TokenUser(models.Model): token = models.CharField(max_length=256) user = models.OneToOneField(to='User',null=True,on_delete=models.SET_NULL,db_constraint=False) class Book(models.Model): name = models.CharField(max_length=16) price = models.IntegerField() publish_date = models.DateField()
myserializer.py
from rest_framework import serializers from app01 import models class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' def validate(self, attrs): return attrs
urls.py
"""blog_test URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01.views import BooksView, BookView,Login urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^Login/$', Login.as_view()), url(r'^Books/$', BooksView.as_view()), url(r'^Books/(?P<pk>d+)/$', BookView.as_view()), ]
views.py
from django.shortcuts import render from rest_framework.response import Response # Create your views here. from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView from app01 import models from app01.myserializer import BookSerializer from rest_framework.views import APIView from app01.myAuth import MyAuthentication,MyPermission class BooksView(ListCreateAPIView): authentication_classes = [MyAuthentication] #加上验证的类,如果有多个,会从做到右依次验证 permission_classes = [MyPermission] queryset = models.Book.objects.all() serializer_class = BookSerializer class BookView(RetrieveUpdateDestroyAPIView): authentication_classes = [MyAuthentication] queryset = models.Book.objects.all() serializer_class = BookSerializer import uuid #登录 class Login(APIView): def post(self,request): name = request.data.get('name') pwd = request.data.get('pwd') user = models.User.objects.filter(name=name,pwd=pwd).first() if user: token = uuid.uuid4() models.TokenUser.objects.update_or_create(user=user,defaults={"token":token}) response = {"status":100,"message":"登录成功"} else: response = {"status": 200, "message": "登录失败"} return Response(response)
二:自定义权限组件类
myauth.py 验证类
from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import BasePermission from app01.models import TokenUser from rest_framework.exceptions import AuthenticationFailed class MyAuthentication(BaseAuthentication): #验证过程 def authenticate(self, request): token = request.GET.get('token') token_user = TokenUser.objects.filter(token=token).first() if token_user: return token_user.user,token else: raise AuthenticationFailed('你还未登录,请先登录') class MyPermission(): message = '该用户的权限无法使用该功能' def has_permission(self, request, view): type = int(request.user.type) if type == 2 or type == 3: return True else: return False def has_object_permission(self, request, view, obj): pass
结果1:
结果2:
三:继承BasePermission的权限组件
myauth.py
from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import BasePermission from app01.models import TokenUser from rest_framework.exceptions import AuthenticationFailed class MyAuthentication(BaseAuthentication): #验证过程 def authenticate(self, request): token = request.GET.get('token') token_user = TokenUser.objects.filter(token=token).first() if token_user: return token_user.user,token else: raise AuthenticationFailed('你还未登录,请先登录') class MyPermission(BasePermission): message = '该用户的权限无法使用该功能' def has_permission(self, request, view): type = int(request.user.type) print(type) if type == 2 or type ==3: print(True) return True else: return False
四:权限组件的使用方式
1.局部使用:在需要使用权限验证的视图类中写上变量 permission_classes= [ 权限类名,]
2.全局使用:在settings.py配置文件中,加入 REST_FRAMEWORK = {‘DEFAULT_PERMISSION_CLASSES’:'权限类的具体位置例如(app01.myauth.MyPermission)'}
3.全局使用,局部禁用:在全局使用的基础上,在不需要验证权限的视图类中,将变量 permission_classes 改为 [ ] 即 permission_classes = [ ]
五:权限组件的源代码分析