一、不存数据库的认证

环境:

与上次(Rest Framework:四)数据库连接的一致,数据也一致,这次也使用的是上次的django环境

urls.py

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

models.py

from django.db import models# Create your models here.
# 用户信息
class UserInfo(models.Model):name = models.CharField(max_length=32)# 写choiceuser_choice = ((0, '普通用户'), (1, '会员'), (2, '超级用户'))# 指定choice,可以快速的通过数字,取出文字user_type = models.IntegerField(choices=user_choice, default=0)pwd = models.CharField(max_length=32)# 用户token
class UserToken(models.Model):token = models.CharField(max_length=64)user = models.OneToOneField(to=UserInfo)class Book(models.Model):nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)price = models.DecimalField(max_digits=5, decimal_places=2)publish_date = models.DateField()publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)authors = models.ManyToManyField(to='Author')def __str__(self):return self.nameclass Author(models.Model):nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)age = models.IntegerField()author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)class AuthorDatail(models.Model):nid = models.AutoField(primary_key=True)telephone = models.BigIntegerField()birthday = models.DateField()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.namedef test(self):return self.email

迁移数据库

python3 manage makemigrations
python3 manage migrate

app01/MySerializer.py

from rest_framework import serializers
from app01 import modelsclass BookSerializer(serializers.ModelSerializer):class Meta:model = models.Bookfields = '__all__'class AuthorSerializer(serializers.ModelSerializer):class Meta:model = models.Authorfields = '__all__'class UserSer(serializers.ModelSerializer):class Meta:model = models.UserInfofields='__all__'# 显示用户类型以中文显示user_type=serializers.CharField(source='get_user_type_display')# 上面一句话就ok# user_type=serializers.SerializerMethodField()# def get_user_type(self,obj):#     return obj.get_user_type_display()

app01/MyAuth.py

from rest_framework import exceptions
from app01 import models
from rest_framework.authentication import BaseAuthenticationimport hashlib
from pro_12_17 import settingsdef check_token(token):ret = Trueuser_info=Nonetry:li = token.split('|')md5 = hashlib.md5()md5.update(li[1].encode('utf-8'))md5.update(settings.password.encode('utf-8'))hex = md5.hexdigest()if not hex == li[0]:ret = Falseelse:user_info=li[1]except Exception as e:ret = Falsereturn ret,user_info# 用dnf 认证,写一个类
class LoginAuth(BaseAuthentication):# 函数名必须叫这个名字,接收必须两个参数,第二个参数是request对像def authenticate(self, request):# 从request对像中取出token (也可以从其他地方中取)token = request.query_params.get('token')# ret 是布尔类型,表示验证通过或失败,user_info是user的字典ret, user_info = check_token(token)if ret:# 可以查到,说明认证通过,返回空return user_info, None#   否则会报异常raise exceptions.APIException('认证失败')from rest_framework.permissions import BasePermissionclass UserPermission(BasePermission):# message是出错显示的中文message = '没权限查看'def has_permission(self, request, view):print(request.user)user_type = request.user.user_typeprint(user_type)# 取出用户类型对应的文字# 固定用法:get_字段名字_display()user_type_name = request.user.get_user_type_display()print(user_type_name)if user_type == 2:return Trueelse:return False

views.py

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from app01 import models
import hashlib
import time
from django.core.exceptions import ObjectDoesNotExist
from app01 import MySerializer# Create your views here.def get_token(name):# 生成一个md5对象md5 = hashlib.md5()# 往里添加值,必须是bytes格式# time.time()生成时间戳类型,转成字符串,再encode转成bytes格式md5.update(str(time.time()).encode('utf-8'))md5.update(name.encode('utf-8'))return md5.hexdigest()from rest_framework import exceptions
from app01.MyAuth import LoginAuth
from rest_framework.request import Requestclass Books(APIView):# 列表中类型不能加括号# 认证组件局部使用# authentication_classes = [LoginAuth, ]# 认证组件,局部禁用 authentication_classes = []authentication_classes = []def get(self, request, *args, **kwargs):print(request.user)response = {'status': 100, 'msg': '查询成功'}ret = models.Book.objects.all()book_ser = MySerializer.BookSerializer(ret, many=True)response['data'] = book_ser.datareturn JsonResponse(response, safe=False)# 只能超级用户可以查看作者详情,其他人不能看
from app01.MyAuth import UserPermissionimport json
from pro_12_17 import settingsdef create_token(user_id):md5 = hashlib.md5()md5.update(user_id.encode('utf-8'))md5.update(settings.password.encode('utf-8'))hex = md5.hexdigest()token = hex + '|' + user_idprint(token)return tokenclass Login(APIView):authentication_classes = []def post(self, request, *args, **kwargs):response = {'status': 100, 'msg': '登录成功'}name = request.data.get('name')pwd = request.data.get('pwd')try:user = models.UserInfo.objects.get(name=name, pwd=pwd)user_info_json = json.dumps({"name": user.name, "id": user.pk})token = create_token(str(user.pk))response['token'] = tokenexcept ObjectDoesNotExist as e:response['status'] = 101response['msg'] = '用户名或密码错误'except Exception as e:response['status'] = 102# response['msg']='未知错误'response['msg'] = str(e)return JsonResponse(response, safe=False)

settings.py

REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],# 'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.UserPermission',],
}
password='123'

使用postman验证结果:

先登录:

后查询结果:


二、自定义的频率控制

新环境:

urls.py

url(r'^test/', views.Test.as_view()),

views.py

from django.shortcuts import render,HttpResponse# Create your views here.
from rest_framework.views import APIView
from app01.MyAuth import MyThrotte
class Test(APIView):throttle_classes = [MyThrotte,]def get(self,request):return HttpResponse('ok')

app01/MyAuth.py

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import time'''
#             {'ip1':[时间1 ,时间2],
#             'ip2':[时间1, ],
#             }
#             # (1)取出访问者ip
#             # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
#             # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
#             # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#             # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
#         '''class MyThrotte():visitor_dic = {}def __init__(self):self.history = Nonedef allow_request(self, request, view):# Meta:请求所有的东西的字典# 拿出ip地址ip = request.META.get('REMOTE_ADDR')# 不在字典中,说明是第一次访问ctime = time.time()if ip not in self.visitor_dic:self.visitor_dic[ip] = [ctime, ]return True# 根据当前访问者ip,取出访问的时间列表history = self.visitor_dic[ip]self.history=historywhile history and ctime - history[-1] > 60:history.pop()if len(history) < 3:# 把当前时间放到第0个位置上history.insert(0, ctime)return Truereturn Falsedef wait(self):# 剩余时间ctime = time.time()return 60 - (ctime - self.history[-1])

测试访问:

get 请求方式访问:

http://127.0.0.1:8000/test/,多刷新几次。

三、内置频率控制类的使用(比上面的一种更为方便,简单)

urls.py

url(r'^test/', views.Test.as_view()),

views.py

from django.shortcuts import render,HttpResponse# Create your views here.
from rest_framework.views import APIView
from app01.MyAuth import MyThrottle
class Test(APIView):# 局部使用,打开全局,把局部要关闭掉# throttle_classes = [MyThrottle,]def get(self,request):return HttpResponse('ok')# 显示返回用户信息为中文字符def throttled(self, request, wait):class MyThrottled(exceptions.Throttled):default_detail = '剩余时间'extra_detail_singular = '还剩 {wait} 秒.'extra_detail_plural = '还剩 {wait} 秒'raise MyThrottled(wait)

app01/MyAuth.py

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import timeclass MyThrottle(SimpleRateThrottle):scope = 'aaa'   # scope 是内置的,必须叫这个名名def get_cache_key(self, request, view):# 返回ip地址# ip=request.META.get('REMOTE_ADDR')# return ip# 下面这种比上面的更方便return self.get_ident(request)

settings.py

REST_FRAMEWORK = {# 全局使用:'DEFAULT_THROTTLE_CLASSES''DEFAULT_THROTTLE_CLASSES': ['app01.MyAuth.MyThrottle', ],'DEFAULT_THROTTLE_RATES': {'aaa': '10/m'     # 一分钟可以访问10次}
}

最后测试:

使用postman 测试:


四、解析器

作用:传过来的数据,解析成字典

settings.py

# 全局解析器
REST_FRAMEWORK = {'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser']}

urls.py

url(r'^test/', views.Test.as_view()),

app01/MyAuth.py

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):scope = 'aaa'   # scope 是内置的,必须叫这个名名def get_cache_key(self, request, view):# 返回ip地址# ip=request.META.get('REMOTE_ADDR')# return ip# 下面这种比上面的更方便return self.get_ident(request)

views.py

from django.shortcuts import render,HttpResponse
from rest_framework import exceptions
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser,FormParser
class Test(APIView):# 局部使用,打开全局,把局部要关闭掉# throttle_classes = [MyThrottle,]# 默认解析的格式有:json,form,multi 三种格式,不写默认支持三种parser_classes = [JSONParser,FormParser]   # 最好只写上你在使用的就好def get(self,request):return HttpResponse('ok')def post(self, request):print(request.data)return HttpResponse('post')# 显示返回用户信息为中文字符def throttled(self, request, wait):class MyThrottled(exceptions.Throttled):default_detail = '剩余时间'extra_detail_singular = '还剩 {wait} 秒.'extra_detail_plural = '还剩 {wait} 秒'raise MyThrottled(wait)

使用postman 测试功能:

成功。

不成功时是这样的:

转载于:https://blog.51cto.com/silencezone/2332297

Rest Framework:五、不存数据库认证以及自定义 ,内置频率控制类的使用,解析器...相关推荐

  1. python只能使用内置数据库_Python只能使用内置数据库SQLite,无法访问MS SQLServer、ACCESS或Oracle、MySQL等数据库...

    Python只能使用内置数据库SQLite,无法访问MS SQLServer.ACCESS或Oracle.MySQL等数据库 答:× 幼儿主动与外部环境相互作用的最重要的方式是 ( ). 答:活动 K ...

  2. 基石为勤能补拙的迷宫之旅——第五天(Python基本数据类型及内置方法)

    一.数据可变不可变类型 可变类型:值改变,但是id不变,证明就是在改变原值,是可变类型 l = ['a', 'b'] print(id(l)) l[0] = 'A' print(l) print(id ...

  3. thinkphp mysql函数_thinkphp对数据库操作有哪些内置函数

    getModelName() 获取当前Model的名称 getTableName() 获取当前Model的数据表名称 switchModel(type,vars=array()) 动态切换模型 tab ...

  4. ES6学习笔记(五):轻松了解ES6的内置扩展对象

    前面分享了四篇有关ES6相关的技术,如想了解更多,可以查看以下连接 <ES6学习笔记(一):轻松搞懂面向对象编程.类和对象> <ES6学习笔记(二):教你玩转类的继承和类的对象> ...

  5. 华为ac配置radius认证服务器_AC6005内置portal+外置radius认证失败

    AC配置 # portal local-server ip 10.66.99.2 portal local-server https ssl-policy default_policy port 84 ...

  6. Apereo CAS 5.0.X 配置数据库认证方式

    Apereo CAS 5.0.X 使用Spring Boot的方式重构了项目,配置也发生了很大的变化.配置文件都在cas项目下的WEB-INF/classes目录下面,配置文件较多,后边详细说,这里先 ...

  7. Django rest framework之限流Throttling、内置过滤功能及第三方过滤功能及分页Pagination

    文章目录 1.限流Throttling 1.1.自定义频率类 1.1.1.编写频率类 1.1.2.全局使用 1.1.3.局部使用 1.2.内置频率类 1.2.1.根据用户ip限制 1.2.2.限制匿名 ...

  8. python的变量对大小写并不敏感_Robot Framework 内置变量

    转自:https://blog.csdn.net/qq_26886929/article/details/53907755 Robot Framework 内部提供了一下直接可用的内置变量 1. 操作 ...

  9. Robot Framework 内置变量

    Robot Framework 内置变量 转自:https://blog.csdn.net/qq_26886929/article/details/53907755 Robot Framework 内 ...

最新文章

  1. LIVE 预告 | 达摩院王玮:超大规模中文理解生成联合模型PLUG
  2. 04-java学习-选择结构
  3. python输入程序_Python 程序设计中的输入与输出介绍
  4. 第二章 使用unittest模块扩展功能测试
  5. 本地构建和自动化构建_构建自动化面板
  6. allergo 导出光辉配置_请教Allegro导出光绘文件的层要选择哪些层?
  7. 企业级私有registry Harbor通过https访问的详细配置
  8. python从入门到精通pdf-跟老齐学Python:从入门到精通 完整版PDF[7MB]
  9. 如何写好一篇博客(文章)
  10. 微信红包软件可测试,微信抢红包神器测试g2020
  11. 信捷XD/XC系列PLC 控制台达B2系列伺服电机程序,手动 自动,循环,循环次数设定
  12. network secruity studay day3
  13. c语言中应用程序错误,大师搞定win7系统提示应用程序错误0xc0000409的解决方案
  14. 人物回眸效果怎么用Vegas设置
  15. 区块链基本原理及其技术实现 - 姜家志 | JTalk 第五期
  16. Centos 系统优化
  17. Go 文件操作(创建、打开、读、写)
  18. 【Python】Matplotlib绘制三维马鞍面
  19. 泛微OA自开发接口并发布
  20. 麻城理工大学计算机系,填报湖北工业大学计算机专业太TMD难了

热门文章

  1. 图机器学习【从理论到实战】
  2. 身份证正则表达式(常见)
  3. VMware启动虚拟机时电脑蓝屏解决办法
  4. 多线程-线程锁-while循环
  5. 详解jar包的启动命令
  6. 计算机组成原理实验六刘学民,计算机组成原理实验报告 第六周实验
  7. 如何用织梦仿制php网站首页,dedecms仿站如何做
  8. 解除禁止复制的若干种方法
  9. CocosCreator 全局Touch事件
  10. java 内存回收参数_JAVA虚拟机内存回收算法与调优参数