zoukankan      html  css  js  c++  java
  • Django rest framework 简易使用方法

    Django rest framework 工具包做API非常方便。

    下面简单说一下几个功能的实现方法。

    实现功能为,匿名用户访问首页一分钟能访问3次,登录用户一分钟访问6次,只有登录用户才能访问order页面。

    第一步,注册app

     1 INSTALLED_APPS = [
     2     'django.contrib.admin',
     3     'django.contrib.auth',
     4     'django.contrib.contenttypes',
     5     'django.contrib.sessions',
     6     'django.contrib.messages',
     7     'django.contrib.staticfiles',
     8     'app.apps.AppConfig',
     9     'rest_framework',  #注册
    10 ]

    settings文件注册app

    第二步,定义URL,注意url路径最好使用名词。我们这里注册三个视图函数的url,实现验证,首页和定单页面。

     1 from django.conf.urls import url
     2 from django.contrib import admin
     3 from app import views
     4 
     5 urlpatterns = [
     6     url(r'^admin/', admin.site.urls),
     7     url(r'^auth/', views.AuthView.as_view()),  #验证
     8     url(r'^index/', views.IndexView.as_view()), #首页
     9     url(r'^order/', views.OrderView.as_view()),  #定单
    10 ] 

    url文件设置路由

    第三步,auth视图函数

     1 from rest_framework.views import APIView
     2 from rest_framework.request import Request
     3 from django.http import JsonResponse,HttpResponse
     4 
     5 from app.utils.commons import gen_token
     6 from app.utils.auth import LuffyAuthentication
     7 from app.utils.throttle import LuffyAnonRateThrottle,LuffyUserRateThrottle
     8 from app.utils.permission import LuffyPermission
     9 from . import models
    10 
    11 class AuthView(APIView):
    12 
    13     """
    14     认证相关视图
    15     由于继承了APIView,所以csrf就没有了,具体的源代码只是有一个装饰器,
    16     加上了csrf_exempt装饰器,屏蔽了csrf
    17     写法是在return的时候csrf_exempt(view) 和@使用装饰器效果是一样的,这种写法还可以写在url路由中。
    18     """
    19     def post(self,request,*args,**kwargs):
    20         """
    21         用户登录功能
    22         :param request:
    23         :param args:
    24         :param kwargs:
    25         :return:
    26         """
    27         ret = {'code': 1000, 'msg': None}
    28         # 默认要返回的信息
    29         user = request.data.get('username')
    30         # 这里的request已经不是原来的request了
    31         pwd = request.data.get('password')
    32         user_obj = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
    33         if user_obj:
    34             tk = gen_token(user)  #返回一个哈希过得字符串
    35             #进行token验证
    36             models.Token.objects.update_or_create(user=user_obj, defaults={'token': tk})
    37             # 数据库存入一个token信息
    38             ret['code'] = 1001
    39             ret['token'] = tk
    40         else:
    41             ret['msg'] = "用户名或密码错误"
    42         return JsonResponse(ret)

    上面的代码主要是实现了一个验证的功能,通过gen_token函数来验证,并存入数据库信息。

    gen_token单独写到一个utils目录下的auth.py文件中。代码如下:

    1 def gen_token(username):
    2     import time
    3     import hashlib
    4     ctime = str(time.time())
    5     hash = hashlib.md5(username.encode('utf-8'))
    6     hash.update(ctime.encode('utf-8'))
    7     return hash.hexdigest()

    通过时间和哈希等生成一个不重复的字符串。

    第四步,index视图函数

     1 class IndexView(APIView):
     2     """
     3     用户认证
     4         http://127.0.0.1:8001/v1/index/?tk=sdfasdfasdfasdfasdfasdf
     5         获取用户传入的Token
     6 
     7     首页限制:request.user
     8         匿名:5/m
     9         用户:10/m
    10     """
    11     authentication_classes = [LuffyAuthentication,]
    12     #认证成功返回一个用户名,一个对象,不成功就是None
    13     throttle_classes = [LuffyAnonRateThrottle,LuffyUserRateThrottle]
    14     #访问次数限制,如果合格都为True
    15     def get(self,request,*args,**kwargs):
    16         return HttpResponse('首页')

    同样,将LuffyAuthenticationLuffyAnonRateThrottle,LuffyUserRateThrottle写到了utils目录下。代码如下:

    auth.py :

     1 from rest_framework.authentication import BaseAuthentication
     2 from rest_framework import exceptions
     3 from app import models
     4 class LuffyAuthentication(BaseAuthentication):
     5     def authenticate(self, request):
     6         tk = request.query_params.get('tk')
     7         if not tk:
     8             return (None,None)
     9             # raise exceptions.AuthenticationFailed('认证失败')
    10 
    11         token_obj = models.Token.objects.filter(token=tk).first()
    12         if not token_obj:
    13             return (None,None)
    14 
    15         return (token_obj.user,token_obj)

    验证是否为登录用户,如果之前没有登陆过,则将token信息存到数据库

    throttle.py :

     1 from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
     2 
     3 
     4 class LuffyAnonRateThrottle(SimpleRateThrottle):
     5 
     6     scope = "luffy_anon"
     7 
     8     def allow_request(self, request, view):
     9         """
    10         Return `True` if the request should be allowed, `False` otherwise.
    11         """
    12         if request.user:
    13             return True
    14 
    15         # 获取当前访问用户的唯一标识
    16         self.key = self.get_cache_key(request, view)
    17         # 根据当前用户的唯一标识,获取所有访问记录
    18         # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
    19         self.history = self.cache.get(self.key, [])
    20         # 获取当前时间
    21         self.now = self.timer()
    22 
    23         # Drop any requests from the history which have now passed the
    24         # throttle duration
    25         while self.history and self.history[-1] <= self.now - self.duration:
    26             self.history.pop()
    27         if len(self.history) >= self.num_requests:   #判断访问次数是否大于限制次数
    28             return self.throttle_failure()
    29         return self.throttle_success()  #返回True
    30 
    31     def get_cache_key(self, request, view):
    32         return 'throttle_%(scope)s_%(ident)s' % {
    33             'scope': self.scope,
    34             'ident': self.get_ident(request),
    35 
    36             # 判断是否为代理等等
    37 
    38         }
    39 
    40 class LuffyUserRateThrottle(SimpleRateThrottle):
    41     scope = "luffy_user"
    42     def allow_request(self, request, view):
    43         """
    44         Return `True` if the request should be allowed, `False` otherwise.
    45         """
    46         if not request.user:   #判断登录直接返回True
    47             return True
    48         # 获取当前访问用户的唯一标识
    49         # 用户对所有页面
    50         # self.key = request.user.user
    51 
    52         self.key = request.user.user + view.__class__.__name__
    53         # 用户对单页面的访问限制
    54 
    55         # 根据当前用户的唯一标识,获取所有访问记录
    56         # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
    57         self.history = self.cache.get(self.key, [])
    58         # 获取当前时间
    59         self.now = self.timer()
    60 
    61         # Drop any requests from the history which have now passed the
    62         # throttle duration
    63         while self.history and self.history[-1] <= self.now - self.duration:
    64             self.history.pop()
    65         if len(self.history) >= self.num_requests:   #访问次数的限制
    66             return self.throttle_failure()
    67         return self.throttle_success()   #返回True

    限制匿名用户和登录用户的访问次数,需要从settings中的配置拿去配置信息。

    permission.py

     1 from rest_framework.permissions import BasePermission
     2 
     3 
     4 class LuffyPermission(BasePermission):
     5     def has_permission(self, request, view):
     6         """
     7         Return `True` if permission is granted, `False` otherwise.
     8         """
     9         if request.user:
    10             return True
    11         return False

    权限控制

    第五步,order视图函数

     1 class OrderView(APIView):
     2     """
     3     订单页面:只有登录成功后才能访问
     4         - 认证(匿名和用户)
     5         - 权限(用户)
     6         - 限制()
     7     """
     8     authentication_classes = [LuffyAuthentication, ]
     9     permission_classes = [LuffyPermission,] #登录就返回True
    10     throttle_classes = [LuffyAnonRateThrottle, LuffyUserRateThrottle]
    11 
    12     def get(self,request,*args,**kwargs):
    13 
    14         return HttpResponse('订单')

    第六步,settings配置

    1 REST_FRAMEWORK = {
    2     'UNAUTHENTICATED_USER': None,
    3     'UNAUTHENTICATED_TOKEN': None,
    4     "DEFAULT_THROTTLE_RATES": {
    5         'luffy_anon': '3/m', #匿名用户一分钟访问3次
    6         'luffy_user': '6/m'  #登录用户一分钟访问6次
    7     },
    8 }

    最后,实现功能为,匿名用户访问首页一分钟能访问3次,登录用户一分钟访问6次,只有登录用户才能访问order页面。

    学习Django rest framework需要随时查看源代码,判断源代码的逻辑思路来自定义自己的功能,如此学习效率极高。

  • 相关阅读:
    C#中的配置文件自定义解析 [转帖]
    pagevisibility event
    [转] 翻译:web制作、开发人员需知的Web缓存知识
    离开和新的开始
    为什么我要自己写html5游戏引擎
    html5游戏长宽设置
    防止横竖屏时,iphone自动缩放的一段代码
    image to base64 工具
    一段代码,给游戏添加统一的封面和旋屏提示
    程序员应该具备的知识和技术(转)
  • 原文地址:https://www.cnblogs.com/ArmoredTitan/p/7882272.html
Copyright © 2011-2022 走看看