Django中rest_framework的認證組件,權限組件,頻率組件,序列化組件的最簡化版接口

urlpython

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^login/', views.Login.as_view()),

    # Book表
    url(r'^books/$',views.BookHandle.as_view({
        'get':'list',
        'post':'create'
    })),
    url(r'^books/(?P<pk>\d+)/',views.BookHandle.as_view({
        'get':'retrieve',
        'put':'update',
        'delete':'destroy'
    })),
# 'get': 'retrieve',
# 'put': 'update',
# 'delete': 'destroy'

    # Author表
    url(r'^authors/$',views.AuthorHandle.as_view({
        'get':'list',
        'post':'create'
    })),
    url(r'^authors/(?P<pk>\d+)/',views.AuthorHandle.as_view({
        'get':'retrieve',
        'put':'update',
        'delete':'destroy'
    })),

    # Publish表
    url(r'^publishs/$',views.PublishHandle.as_view({
        'get':'list',
        'post':'create'
    })),
    url(r'^publishs/(?P<pk>\d+)/',views.PublishHandle.as_view({
        'get':'retrieve',
        'put':'update',
        'delete':'destroy'
    })),
]

  

viewgit


from app01.all_serializers import BookSerializer,AuthorSerializer,PublishSerializer
from app01 import models
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.views import APIView
import uuid

# Create your views here.


# 登錄設置token,爲認證作鋪墊
class Login(APIView):
    # 200:成功 400:失敗
    dic = {'code':None,'username':None,'msg':None,'token':None}
    def post(self,request):
        uname = request.data.get('username')
        upwd = request.data.get('password')
        user_obj = models.User.objects.filter(username=uname,password=upwd).first()
        if user_obj:
            random_str = uuid.uuid4()
            models.My_token.objects.update_or_create(
                defaults={'token':random_str},
                user = user_obj
            )
            self.dic['code'] = 200
            self.dic['username'] = uname
            self.dic['msg'] = '登錄成功'
            self.dic['token'] = random_str

        else:
            self.dic['code'] = 400
            self.dic['msg'] = '登錄失敗'

        return Response(self.dic)


# 認證組件的類
from rest_framework.exceptions import AuthenticationFailed  #認證失敗,拋出異常
from rest_framework.authentication import BaseAuthentication

class UserInfo(BaseAuthentication):
    # 這個方法能夠pass,可是必須存在
    def authenticate_header(self,request):
        pass

    # authenticate方法固定的,而且必須有個參數,這個參數是新的request對象,不信,看源碼
    def authenticate(self,request):
        # query_params至關於GET.get,獲取get請求時,?後面攜帶的參數
        token = request.query_params.get('token')
        my_token_obj = models.My_token.objects.filter(token=token).first()
        if my_token_obj:
            # 返回的第一個參數request.user是User表的對象,第二個參數request.auth是token
            return my_token_obj.user,token
        else:
            raise AuthenticationFailed('認證失敗')


#權限組件的類
from rest_framework.permissions import BasePermission

class UserPermission(BasePermission):
    message = 'VIP以上權限才能訪問'
    # 這個方法必須存在
    def has_permission(self,request,view):
        # 認證組件的時候,返回兩個值,一個是request.user,一個是request.auth.
        if request.user.usertype >= 2 :
            return True
        return False
        # return True


#訪問頻率組件的類
from rest_framework.throttling import BaseThrottle
import time

#定義一個全局字典,保證用戶訪問事後,這個字典裏面的值還存在
throttle_dic = {}
class MyThrottle(BaseThrottle):

    mytime = 10
    mycount = 5
    # 當前請求的時間

    # 定義方法 方法名和參數不能變
    def allow_request(self, request, view):
        # 獲取登陸主機的id
        id = request.META.get('REMOTE_ADDR')

        # 定義一個類變量,由於wait方法會用到
        self.now_time = time.time()

        # 當這個主機ID 沒有請求過,請繼續執行
        if id not in throttle_dic:
            throttle_dic[id] = []

        # 定義一個類變量,用來定義這個字典裏面的列表,在wait方法中會用到
        self.lis = throttle_dic[id]
        # 當這個主機ID有值,且當前時間-列表最後存的時間,大於時間間隔10s時,刪除掉最後存的時間,依次循環
        while self.lis and self.now_time - self.lis[-1] >= self.mytime :
            self.lis.pop()
        # 當主機ID裏面存的數據的數量小於定義的頻率次數(5次),把當前時間存入這個列表,且證實能夠訪問
        if len(self.lis) < self.mycount :
            self.lis.insert(0,self.now_time)
            return True
        # 不然,說明在規定的時間內,訪問的次數超過上限
        else:
            return False

    # 這個方法必須存在
    def wait(self):
        return self.lis[-1] + self.mytime - self.now_time



#書籍表的視圖函數
class BookHandle(ModelViewSet):
#添加認證組件,參數不能變
authentication_classes = [UserInfo,]
#添加權限組件,參數不能變
permission_classes = [UserPermission,]
#添加頻率組件,參數不能變
throttle_classes = [MyThrottle,]

queryset = models.Book.objects.all()
# 序列化組件,必需要有
serializer_class = BookSerializer

#做者表的視圖函數
class AuthorHandle(ModelViewSet):
# 添加認證組件,參數不能變
authentication_classes = [UserInfo, ]
# 添加權限組件,參數不能變
permission_classes = [UserPermission, ]
# 添加頻率組件,參數不能變
throttle_classes = [MyThrottle, ]

queryset = models.Author.objects.all()
# 序列化組件,必需要有
serializer_class = AuthorSerializer

#出版社表的序列化組件
class PublishHandle(ModelViewSet):
# 添加認證組件,參數不能變
authentication_classes = [UserInfo, ]
# 添加權限組件,參數不能變
permission_classes = [UserPermission, ]
# 添加頻率組件,參數不能變
throttle_classes = [MyThrottle, ]

queryset = models.Publish.objects.all()
# 序列化組件,必需要有
serializer_class = PublishSerializer

  

all_serializers
from rest_framework import serializers
from app01 import models

# Book表的序列化組件
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
    #多對一字段(不要跟字段名重名) 參數source,read_only這兩個參數要有
    publish_name = serializers.CharField(max_length=32,source='publish.name',read_only=True)

    #多對多字段(不要跟字段名重名)
    author_name = serializers.SerializerMethodField()
    def get_author_name(self,obj):
        lis = []
        author_obj_list = obj.authors.all()

        for author_obj in author_obj_list:
            dic = {}
            dic['name'] = author_obj.name
            lis.append(dic)

        return lis


# Author表的序列化組件
class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = '__all__'


# Publish表的序列化組件
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = '__all__'
 

  

modelsdjango

from django.db import models

# Create your models here.
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()

class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    # publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2) 
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) #多對一到Publish表
    authors=models.ManyToManyField(to='Author',) #多對多到Author表

class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    my_type = ((1,'IP'),(2,'VIP'),(3,'SVIP'))
    usertype = models.IntegerField(choices=my_type,default=1)

class My_token(models.Model):
    token = models.CharField(max_length=32)
    user = models.OneToOneField('User')
相關文章
相關標籤/搜索