rest framework

from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from django.http import JsonResponse
from appone import models
from rest_framework.versioning import URLPathVersioning
from rest_framework.authentication import BaseAuthentication
from rest_framework.request import Request
from rest_framework import exceptions
from rest_framework.throttling import SimpleRateThrottle


from rest_framework.authentication import SessionAuthentication

def gen_token(username):
    import time
    import hashlib
    ctime = str(time.time())
    hash = hashlib.md5(username.encode('utf-8'))
    hash.update(ctime.encode('utf-8'))
    return hash.hexdigest()
#################### 验证相关######################
class CustomAuthentication(BaseAuthentication):
    def authenticate(self, request):
        """
        Authenticate the request and return a two-tuple of (user, token).
        """
        tk = request.query_params.get('tk')
        if not tk:
            '''
            未登录用户
            '''
            return (None,None)
        '''已登录用户'''
        token_obj = models.Token.objects.filter(token=tk).first()
        if token_obj:
            # (UserInfo对象,Token对象)
            return (token_obj.user,token_obj)
        raise exceptions.AuthenticationFailed("认证失败")

    def authenticate_header(self, request):
        """
        Return a string to be used as the value of the `WWW-Authenticate`
        header in a `401 Unauthenticated` response, or `None` if the
        authentication scheme should return `403 Permission Denied` responses.
        """
        # return 'Basic realm=api'
        pass

#################### 权限控制######################
from rest_framework.permissions import AllowAny,BasePermission
class CustomPermission(BasePermission):
    message = "无权限"
    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        '''登录用户才能访问'''
        if request.user:
            return True
        return False

#################### 限制访问次数######################
class CustomAnonRateThrottle(SimpleRateThrottle):
    '''
    未登录用户配置
    '''
    scope = 'Luffy_anon'

    def get_cache_key(self, request, view):
        return 'throttle_%(scope)s_%(ident)s'%{
            'scope':self.scope,
            'ident':self.get_ident(request)
        }

    def allow_request(self, request, view):
        #已登录用户不管
        if request.user:
            return True

        #未登陆
        self.key = self.get_cache_key(request, view)
        self.history = self.cache.get(self.key,[])

        self.now = self.timer()


        while self.history and self.history[-1] <= self.now - self.duration:
            self.history.pop()
        if len(self.history) >= self.num_requests:
            return self.throttle_failure()
        return self.throttle_success()
class CustomUserRateThrottle(SimpleRateThrottle):
    scope = 'Luffy_user'

    def allow_request(self, request, view):
        if not request.user:
            return True

        # 获取当前访问用户的唯一标识
        # 用户对所有页面
        # self.key = request.user.user
        # 用户对单页面
        self.key = request.user.user + view.__class__.__name__
        self.history = self.cache.get(self.key,[])

        self.now = self.timer()


        while self.history and self.history[-1] <= self.now - self.duration:
            self.history.pop()
        if len(self.history) >= self.num_requests:
            return self.throttle_failure()
        return self.throttle_success()



class LoginView(APIView):
    '''
    登录,无限制,用户发送用户名和密码,登录返回token
    '''
    # versioning_class = URLPathVersioning
    def get(self,request,*args,**kwargs):
        return HttpResponse("login get page")
    def post(self,request,*args,**kwargs):
        ret = {'code': 1000, 'msg': None}
        print(request.data)
        user = request.data.get('user')
        pwd = request.data.get('pwd')

        user_obj = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user_obj:
            tk = gen_token(user)
            models.Token.objects.update_or_create(user=user_obj, defaults={'token': tk})
            ret['code'] = 1001
            ret['token'] = tk
        else:
            ret['msg'] = "用户名或密码错误"
        return JsonResponse(ret)

class indexView(APIView):
    '''
    首页,所有人都能访问,限制【匿名用户10/m,登录20/m】
    '''
    authentication_classes = [CustomAuthentication, ]
    # permission_classes = [CustomPermission, ]
    throttle_classes = [CustomAnonRateThrottle, CustomUserRateThrottle]

    def get(self, request, *args, **kwargs):
        a = self.dispatch
        # print(request.user)
        # print(self.request.user.user)
        return HttpResponse('index get page')

    def post(self,request,*args,**kwargs):
        return HttpResponse('index post page')

class OrderView(APIView):
    '''
    订单,登录成功之后,才能查看;限制【登录20/m】
    '''
    authentication_classes = [CustomAuthentication, ]
    permission_classes = [CustomPermission, ]
    throttle_classes = [CustomUserRateThrottle,]

    def get(self, request, *args, **kwargs):
        a = self.dispatch
        return HttpResponse('order get page')
    def post(self,request,*args,**kwargs):
        print(request.data)
        return HttpResponse("order post page")





############################路由################
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet,ModelViewSet
from rest_framework.viewsets import mixins

class RouteSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

# #手动路由
# class RouterView(APIView):
#     def get(self,request,*args,**kwargs):
#         pk = kwargs.get("pk")
#         if pk:
#             obj = models.UserInfo.objects.filter(pk=pk).first()
#             ser = RouteSerializer(instance=obj,many=False)
#         else:
#             user_list = models.UserInfo.objects.all()
#             ser = RouteSerializer(instance=user_list, many=True)
#         return Response(ser.data)


class RouterView(ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = RouteSerializer



#########################分页######################
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

# class StandardResultsSetPagination(PageNumberPagination):
#     '''根据页码进行分页'''
#     # 默认每页显示的数据条数
#     page_size = 3
#     # 获取URL参数中设置的每页显示数据条数
#     page_size_query_param = 'page_size'
#
#     # 获取URL参数中传入的页码key
#     page_query_param = 'page'
#
#     # 最大支持的每页显示的数据条数
#     max_page_size = 5

# class StandardResultsSetPagination(LimitOffsetPagination):
#     '''位置和个数进行分页'''
#     # 默认每页显示的数据条数
#     default_limit = 3
#     # URL中传入的显示数据条数的参数
#     limit_query_param = 'limit'
#     # URL中传入的数据位置的参数
#     offset_query_param = 'offset'
#     # 最大每页显得条数
#     max_limit = None
class StandardResultsSetPagination(CursorPagination):
    '''游标分页'''
    # URL传入的游标参数
    cursor_query_param = 'cursor'
    # 默认每页显示的数据条数
    page_size = 2
    # URL传入的每页显示条数的参数
    page_size_query_param = 'page_size'
    # 每页显示数据最大条数
    max_page_size = 1000

    # 根据ID从大到小排列
    ordering = "id"
class PagerView(APIView):

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()

        # 实例化分页对象,获取数据库中的分页数据
        paginator = StandardResultsSetPagination()
        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)

        # 序列化对象
        serializer = PageSerializer(page_user_list, many=True)

        # 生成分页和数据
        response = paginator.get_paginated_response(serializer.data)
        return response


############### 渲染 ##############
# 用户想要的数据格式:
# http://127.0.0.1:8002/render/?format=json
# http://127.0.0.1:8002/render.json
# 我支持的所有格式: json,admin,form

from rest_framework.renderers import JSONRenderer,AdminRenderer,BrowsableAPIRenderer,HTMLFormRenderer
class RenderSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

from rest_framework.negotiation import DefaultContentNegotiation

class RenderView(APIView):
    # 解析器:content-type

    # URL中format传入的参数
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer,AdminRenderer,HTMLFormRenderer]

    def get(self,request,*args,**kwargs):
        #form 格式
        # user_list = models.UserInfo.objects.all().first()
        # ser = RenderSerializer(instance=user_list,many=False)
        #admin 格式
        user_list = models.UserInfo.objects.all()
        ser = RenderSerializer(instance=user_list, many=True)
        return Response(ser.data)

  

posted @ 2017-11-29 18:06  hedeyong11  阅读(249)  评论(0编辑  收藏  举报