zoukankan      html  css  js  c++  java
  • Django Rest Framework --- 权限组件

    一、权限组件的作用

      不同的用户使用的功能是不一致的,例如爱奇艺有些视频需要会员一样,我们可以对登录的用户进行权限的认证,来判断其能不能使用这个功能。当然权限认证的前提是已经用户认证了,因此需要在最后一个用户认证类中返回认证成功的用户。

    • 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  =  [ ]

    五、权限组件的源代码分析

  • 相关阅读:
    SaaS模式应用之多租户系统开发(单数据库多Schema设计)
    web-api POST body object always null
    linq to js 用法
    c#导出数据到csv文本文档中,数据前面的0不见了解决方法
    金蝶BOS元模型分析
    DotNet 资源大全中文版
    JavaScript中的类方法、对象方法、原型方法
    解决System.Data.SqlClient.SqlException (0x80131904): Timeout 时间已到的问题
    在需要隐藏navigationController控制器
    升级macOS Sierra系统 导致错误 app: resource fork, Finder information, or similar detritus not allowed
  • 原文地址:https://www.cnblogs.com/846617819qq/p/10617328.html
Copyright © 2011-2022 走看看