Django rest framework工具包简单用法示例


Posted in Python onJuly 20, 2018

本文实例讲述了Django rest framework工具包简单用法。分享给大家供大家参考,具体如下:

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

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

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

第一步,注册app

INSTALLED_APPS = [
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  'app.apps.AppConfig',
  'rest_framework', #注册
]

settings文件注册app

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

from django.conf.urls import url
from django.contrib import admin
from app import views
urlpatterns = [
  url(r'^admin/', admin.site.urls),
  url(r'^auth/', views.AuthView.as_view()), #验证
  url(r'^index/', views.IndexView.as_view()), #首页
  url(r'^order/', views.OrderView.as_view()), #定单
]

url文件设置路由

第三步,auth视图函数

from rest_framework.views import APIView
from rest_framework.request import Request
from django.http import JsonResponse,HttpResponse
from app.utils.commons import gen_token
from app.utils.auth import LuffyAuthentication
from app.utils.throttle import LuffyAnonRateThrottle,LuffyUserRateThrottle
from app.utils.permission import LuffyPermission
from . import models
class AuthView(APIView):
  """
  认证相关视图
  由于继承了APIView,所以csrf就没有了,具体的源代码只是有一个装饰器,
  加上了csrf_exempt装饰器,屏蔽了csrf
  写法是在return的时候csrf_exempt(view) 和@使用装饰器效果是一样的,这种写法还可以写在url路由中。
  """
  def post(self,request,*args,**kwargs):
    """
    用户登录功能
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    ret = {'code': 1000, 'msg': None}
    # 默认要返回的信息
    user = request.data.get('username')
    # 这里的request已经不是原来的request了
    pwd = request.data.get('password')
    user_obj = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
    if user_obj:
      tk = gen_token(user) #返回一个哈希过得字符串
      #进行token验证
      models.Token.objects.update_or_create(user=user_obj, defaults={'token': tk})
      # 数据库存入一个token信息
      ret['code'] = 1001
      ret['token'] = tk
    else:
      ret['msg'] = "用户名或密码错误"
    return JsonResponse(ret)

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

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

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()

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

第四步,index视图函数

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

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

auth.py :

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from app import models
class LuffyAuthentication(BaseAuthentication):
  def authenticate(self, request):
    tk = request.query_params.get('tk')
    if not tk:
      return (None,None)
      # raise exceptions.AuthenticationFailed('认证失败')
    token_obj = models.Token.objects.filter(token=tk).first()
    if not token_obj:
      return (None,None)
    return (token_obj.user,token_obj)

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

throttle.py :

from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
class LuffyAnonRateThrottle(SimpleRateThrottle):
  scope = "luffy_anon"
  def allow_request(self, request, view):
    """
    Return `True` if the request should be allowed, `False` otherwise.
    """
    if request.user:
      return True
    # 获取当前访问用户的唯一标识
    self.key = self.get_cache_key(request, view)
    # 根据当前用户的唯一标识,获取所有访问记录
    # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
    self.history = self.cache.get(self.key, [])
    # 获取当前时间
    self.now = self.timer()
    # Drop any requests from the history which have now passed the
    # throttle duration
    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() #返回True
  def get_cache_key(self, request, view):
    return 'throttle_%(scope)s_%(ident)s' % {
      'scope': self.scope,
      'ident': self.get_ident(request),
      # 判断是否为代理等等
    }
class LuffyUserRateThrottle(SimpleRateThrottle):
  scope = "luffy_user"
  def allow_request(self, request, view):
    """
    Return `True` if the request should be allowed, `False` otherwise.
    """
    if not request.user:  #判断登录直接返回True
      return True
    # 获取当前访问用户的唯一标识
    # 用户对所有页面
    # self.key = request.user.user
    self.key = request.user.user + view.__class__.__name__
    # 用户对单页面的访问限制
    # 根据当前用户的唯一标识,获取所有访问记录
    # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
    self.history = self.cache.get(self.key, [])
    # 获取当前时间
    self.now = self.timer()
    # Drop any requests from the history which have now passed the
    # throttle duration
    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()  #返回True

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

permission.py

from rest_framework.permissions import BasePermission
class LuffyPermission(BasePermission):
  def has_permission(self, request, view):
    """
    Return `True` if permission is granted, `False` otherwise.
    """
    if request.user:
      return True
    return False

权限控制

第五步,order视图函数

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

第六步,settings配置

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

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

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

希望本文所述对大家基于Django框架的Python程序设计有所帮助。

Python 相关文章推荐
Python解决鸡兔同笼问题的方法
Dec 20 Python
Python之批量创建文件的实例讲解
May 10 Python
NumPy.npy与pandas DataFrame的实例讲解
Jul 09 Python
python匹配两个短语之间的字符实例
Dec 25 Python
在Pycharm中修改文件默认打开方式的方法
Jan 17 Python
python3爬虫学习之数据存储txt的案例详解
Apr 24 Python
python实现百度OCR图片识别过程解析
Jan 17 Python
python从Oracle读取数据生成图表
Oct 14 Python
python将下载到本地m3u8视频合成MP4的代码详解
Nov 24 Python
python 使用csv模块读写csv格式文件的示例
Dec 02 Python
Pytorch 中net.train 和 net.eval的使用说明
May 22 Python
python pandas 解析(读取、写入)CSV 文件的操作方法
Dec 24 Python
Django 中使用流响应处理视频的方法
Jul 20 #Python
Python实现手写一个类似django的web框架示例
Jul 20 #Python
python 实现求解字符串集的最长公共前缀方法
Jul 20 #Python
python实现求两个字符串的最长公共子串方法
Jul 20 #Python
Django基础知识与基本应用入门教程
Jul 20 #Python
opencv python 2D直方图的示例代码
Jul 20 #Python
Linux下python制作名片示例
Jul 20 #Python
You might like
php 数组排序 array_multisort与uasort的区别
2011/03/24 PHP
PHP学习 变量使用总结
2011/03/24 PHP
PHP学习之数组的定义和填充
2011/04/17 PHP
Erlang的运算符(比较运算符,数值运算符,移位运算符,逻辑运算符)
2012/07/23 PHP
php通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
PHP Static延迟静态绑定用法分析
2016/03/16 PHP
php版微信数据统计接口用法示例
2016/10/12 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
2013/12/02 Javascript
JavaScript保留两位小数的2个自定义函数
2014/05/05 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
基于jQuery实现拖拽图标到回收站并删除功能
2015/11/25 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
JS生成不重复的随机数组的简单实例
2016/07/10 Javascript
jQuery实现鼠标选中文字后弹出提示窗口效果【附demo源码】
2016/09/05 Javascript
node koa2实现上传图片并且同步上传到七牛云存储
2017/07/31 Javascript
webpack打包并将文件加载到指定的位置方法
2018/02/22 Javascript
在Python中用has_key()方法查找键是否存在的教程
2015/05/21 Python
python协程用法实例分析
2015/06/04 Python
Python编程实现及时获取新邮件的方法示例
2017/08/10 Python
利用numpy实现一、二维数组的拼接简单代码示例
2017/12/15 Python
详解Django将秒转换为xx天xx时xx分
2019/09/27 Python
基于Django实现日志记录报错信息
2019/12/17 Python
Python代码生成视频的缩略图的实例讲解
2019/12/22 Python
python3+selenium获取页面加载的所有静态资源文件链接操作
2020/05/04 Python
Python datetime 如何处理时区信息
2020/09/02 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
Python项目实战之使用Django框架实现支付宝付款功能
2021/02/23 Python
C#笔试题和英文面试题
2013/02/07 面试题
高中军训感言200字
2014/02/23 职场文书
企业宗旨标语
2014/06/10 职场文书
5s标语大全
2014/06/23 职场文书
监察建议书
2015/02/04 职场文书
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis