七 解析器

解析器的作用:

-用来解析前台传过来的数据编码方式
urlencoded:form表单:name=lqz&age=
formdata :上传文件:--dadfgdgag--
json:json格式 {"name":"lqz"}
-解析器取的顺序
视图类中
django总settings里取
drf默认的配置文件取
—全局配置
在setting中:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
] }
-局部使用:
在视图类中:
from rest_framework.parsers import JSONParser,MultiPartParser,FormParser
parser_classes = [JSONParser,FormParser]

例子

解析器
局部配置
from rest_framework.parsers import JSONParser
class Book(APIView):
parser_classes = [JSONParser, ]
def get(self,request,*args,**kwargs):
return HttpResponse('ok')
def post(self,request):
print(request.data)
return HttpResponse('post') from rest_framework.parsers import JSONParser,MultiPartParser,FormParser
class Book(APIView):
parser_classes = [JSONParser,FormParser]
def get(self,request,*args,**kwargs):
return HttpResponse('ok')
def post(self,request):
print(request.data)
return HttpResponse('post')

八、认证组件

1、校验是否登陆

    -作用:校验是否登陆
-首先定义一个类,继承BaseAuthentication,写一个方法:authenticate,在方法内部,实
证过程,认证通过,返回None或者两个对象(user,auth),这两个对象,在视图类的request中可以取出来
from rest_framework.authentication import BaseAuthentication
class myAuthen(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
ret = models.UserToken.objects.filter(token=token).first()
if ret:
# return ret.user, ret
# 要写多个认证类,这个地返回None
# 最后一个认证类,返回这俩值
return ret.user, ret
else:
raise AuthenticationFailed('您没有登陆') -局部使用:在视图类中(可以写多个)
authentication_classes = [myAuthen, ]
-全局使用:
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]

2、正常非drf认证代码,update_or_create意思是有则更新,无则创建

class User(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
pwd=models.CharField(max_length=32,null=True)
mychoice=((1,'普通用户'),(2,'超级用户'),(3,'宇宙用户'))
usertyle=models.IntegerField(choices=mychoice,default=1) class UserToken(models.Model):
user=models.OneToOneField(to=User,to_field='nid')
token=models.CharField(max_length=64)

def get_token(username):
import hashlib
import time
md = hashlib.md5()
# update内必须传bytes格式
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest() class Login(APIView):
def post(self, request):
response = MyResponse()
name = request.data.get('name')
pwd = request.data.get('pwd')
user = models.User.objects.filter(name=name, pwd=pwd).first()
if user:
response.msg = '登陆成功'
# 登陆成功,返回一个随机字符串,以后在发请求,都携带这个字符串
token = get_token(name)
response.token = token
# 把随机字符串保存到数据库,有就更新,没有就创建
# ret=models.UserToken.objects.update_or_create(user_id=user.id,kwargs={'token':token})
ret = models.UserToken.objects.update_or_create(user=user, defaults={'token': token}) else:
response.msg = '用户名或密码错误'
response.status =
return JsonResponse(response.get_dic)

3、drf的认证组件用法,return user或者auth

class myAuthen():
def authenticate(self,request):
token = request.query_params.get('token')
ret = models.UserToken.objects.filter(token=token).first()
if ret:
return ret.user,ret
else:
raise AuthenticationFailed('您咩有登陆') def authenticate_header(self,value):
pass from rest_framework.request import Request
from app01 import myserial
class Book(APIView):
authentication_classes = [myAuthen, ]
def get(self, request):
response = MyResponse()
print(request.user.name)
print(request.auth.token)
# 必须登陆才能访问
books = models.Book.objects.all()
ret = myserial.BookSer(instance=books, many=True)
response.msg = '查询成功'
response.data = ret.data
return JsonResponse(response.get_dic, safe=False)

4、先建个auth.py,存入认证组价的功能

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01 import models class myAuthen(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
ret = models.UserToken.objects.filter(token=token).first()
if ret:
# return ret.user, ret
# 要写多个认证类,这个地返回None
# 最后一个认证类,返回这俩值
return ret.user, ret
else:
raise AuthenticationFailed('您没有登陆')

5、若在setting里配置了全局验证,则全局验证,但是视图函数里的login()不需要,则我们参考了顺序是先找局部,在找setting里。所以需要在视图函数里配置

authentication_classes = [],即不需要验证
class Login(APIView):
authentication_classes = []
def post(self, request):
response = MyResponse()
name = request.data.get('name')
pwd = request.data.get('pwd')
user = models.User.objects.filter(name=name, pwd=pwd).first()
if user:
response.msg = '登陆成功'
# 登陆成功,返回一个随机字符串,以后在发请求,都携带这个字符串
token = get_token(name)
response.token = token
# 把随机字符串保存到数据库,有就更新,没有就创建
# ret=models.UserToken.objects.update_or_create(user_id=user.id,kwargs={'token':token})
ret = models.UserToken.objects.update_or_create(user=user, defaults={'token': token}) else:
response.msg = '用户名或密码错误'
response.status =
return JsonResponse(response.get_dic)

6、settings

REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
],
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.myAuthen", ],
"DEFAULT_PERMISSION_CLASSES":["app01.auth.myPermission",] }

7、存的token数据一般存在服务器端数据库里,但是存在压力,第一存在redis里,第二种方式就是不存数据库的token验证,及如下所示

def get_token(id,salt=''):
import hashlib
md=hashlib.md5()
md.update(bytes(str(id),encoding='utf-8'))
md.update(bytes(salt,encoding='utf-8')) return md.hexdigest()+'|'+str(id) def check_token(token,salt=''):
ll=token.split('|')
import hashlib
md=hashlib.md5()
md.update(bytes(ll[-],encoding='utf-8'))
md.update(bytes(salt,encoding='utf-8'))
if ll[]==md.hexdigest():
return True
else:
return False class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
success=check_token(token)
if success:
return
else:
raise AuthenticationFailed('认证失败')
def authenticate_header(self,request):
pass
class Login(APIView):
def post(self,reuquest):
back_msg={'status':,'msg':None}
try:
name=reuquest.data.get('name')
pwd=reuquest.data.get('pwd')
user=models.User.objects.filter(username=name,password=pwd).first()
if user:
token=get_token(user.pk)
# models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
back_msg['status']=''
back_msg['msg']='登录成功'
back_msg['token']=token
else:
back_msg['msg'] = '用户名或密码错误'
except Exception as e:
back_msg['msg']=str(e)
return Response(back_msg)
from rest_framework.authentication import BaseAuthentication
class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
return
else:
raise AuthenticationFailed('认证失败')
def authenticate_header(self,request):
pass class Course(APIView):
authentication_classes = [TokenAuth, ] def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')

九 权限组件

1、校验用户是否有权限访问

-作用:校验用户是否有权限访问
-因为是在认证通过才执行,所以可以取出user
class myPermission():
message = '不是超超级用户,查看不了'
def has_permission(self, request, view):
if request.user.usertyle != :
return False
else:
return True
-局部使用
在视图类中:permission_classes=[myPermission,]
-全局使用
在setting中:
"DEFAULT_PERMISSION_CLASSES":["app01.auth.myPermission",]

2、choices=的写法,一般用性别等不常用的常识

class User(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=)
pwd=models.CharField(max_length=,null=True)
mychoice=((,'普通用户'),(,'超级用户'),(,'宇宙用户'))
usertyle=models.IntegerField(choices=mychoice,default=) class UserToken(models.Model):
user=models.OneToOneField(to=User,to_field='nid')
token=models.CharField(max_length=)

3、eg

from rest_framework.permissions import BasePermission
class myPermission(BasePermission):
message = '不是超超级用户,查看不了'
def has_permission(self, request, view):
if request.user.usertyle != :
return False
else:
return True
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
],
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.myAuthen", ],
"DEFAULT_PERMISSION_CLASSES":["app01.auth.myPermission",] }
from app01.auth import myAuthen
from app01.auth import myPermission class Book(APIView):
# authentication_classes = [myAuthen, ]
# permission_classes=[myPermission,] def get(self, request):
response = MyResponse()
print(request.user.name)
print(request.auth.token)
# 必须登陆才能访问
books = models.Book.objects.all()
ret = myserial.BookSer(instance=books, many=True)
response.msg = '查询成功'
response.data = ret.data
return JsonResponse(response.get_dic, safe=False)

十、频率组件

1、参考原码写的符合频率组件logic的代码

class MyThro():
VISIT_RECORD = {}
# VISIT_RECORD = {ip:[时间1,时间2],ip2:[],ip3:[当前时间]} def __init__(self):
self.history = None def allow_request(self, request, view):
# ()取出访问者ip
# print(request.META)
ip = request.META.get('REMOTE_ADDR')
import time
ctime = time.time()
# ()判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
if ip not in self.VISIT_RECORD:
self.VISIT_RECORD[ip] = [ctime, ]
return True
self.history = self.VISIT_RECORD.get(ip)
# ()循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
while self.history and ctime - self.history[-] > :
self.history.pop()
# ()判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
# ()当大于等于3,说明一分钟内访问超过三次,返回False验证失败
if len(self.history) < :
self.history.insert(, ctime)
return True
else:
return False def wait(self):
import time
ctime = time.time()
return - (ctime - self.history[-])

视图函数使用代码

from app01.auth import MyThro
class Book(APIView):
authentication_classes = [myAuthen, ]
permission_classes=[]
throttle_classes=[MyThro,] def get(self, request):
# request.user
response = MyResponse()
# request.GET
print(request.user.name)
print(request.auth.token)
# 必须登陆才能访问
books = models.Book.objects.all()
ret = myserial.BookSer(instance=books, many=True)
response.msg = '查询成功'
response.data = ret.data
return JsonResponse(response.get_dic, safe=False)

2、使用

    频率:
-定义一个类:
from rest_framework.throttling import SimpleRateThrottle
class MyThro(SimpleRateThrottle):
scope = 'aaa'
def get_cache_key(self, request, view):
# return self.get_ident(request)
return request.META.get('REMOTE_ADDR') -setting中配置
"DEFAULT_THROTTLE_RATES":{
'aaa':'3/msssssss'
} -全局使用:
'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThro',],
-局部使用:
throttle_classes=[MyThro,]

eg.

from rest_framework.throttling import SimpleRateThrottle
class MyThro(SimpleRateThrottle):
scope = 'aaa'
def get_cache_key(self, request, view):
# return self.get_ident(request)
return request.META.get('REMOTE_ADDR')
# return

3、假如全局限制每分钟查看3次,视图函数每分钟10次,则需要在

"DEFAULT_THROTTLE_RATES":{
'aaa':'3/msssssss'
},

from rest_framework.throttling import SimpleRateThrottle
class MyThro(SimpleRateThrottle):
scope = 'aaa'
def get_cache_key(self, request, view):
# return self.get_ident(request)
return request.META.get('REMOTE_ADDR')
# return
将aaa 赋值为10/mmmmms

RESTful规范(二)的更多相关文章

  1. 一、restful规范 二、CBV(View)源代码执行流程 三、drf框架安装和简单使用

    一.restful规范 ''' 它是一个规范,面向资源架构 十条规范 1.API与用户的通讯协议,总是使用HTTPs协议,确保了网络传输的安全性 2.域名 --https://api.example. ...

  2. RESTful规范

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  3. DjangoRestFramework 学习之restful规范 APIview 解析器组件 Postman等

    DjangoRestFramework学习一之restful规范.APIview.解析器组件.Postman等 本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析器组件 ...

  4. RESTful规范1

    RESTful规范 一 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状 ...

  5. Django restful 规范

    一.REST Frame Work REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状态转移&q ...

  6. drf1 rest & restful规范

    web服务交互 我们在浏览器中能看到的每个网站,都是一个web服务.那么我们在提供每个web服务的时候,都需要前后端交互,前后端交互就一定有一些实现方案,我们通常叫web服务交互方案. 目前主流的三种 ...

  7. day89 DjangoRsetFramework学习---restful规范,解析器组件,Postman等

     DjangoRsetFramework学习---restful规范,解析器组件,Postman等           本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析 ...

  8. 18.DjangoRestFramework学习一之restful规范、APIview、解析器组件、Postman等

    一 预备知识 预备知识:django的CBV和FBV CBV(class based view):多用,简单回顾一下 FBV(function based view): CBV模式的简单操作:来个登陆 ...

  9. Django框架(十七)-- CBV源码分析、restful规范、restframework框架

    一.CBV源码分析 1.url层的使用CBV from app01 import views url(r'book/',views.Book.as_view) 2.as_view方法 as_view是 ...

  10. 基于Django的Rest Framework框架的RESTful规范研究

    一.什么是RESTful规范 总的来说:RESTful规范就是一个非技术,人为约定的一个面向资源的架构理念. REST与技术无关,代表的是一种软件架构风格,REST是Representational ...

随机推荐

  1. Win10系列:VC++绘制位图图片

    在使用Direct2D绘制图片的过程中,通过IWICImagingFactory工厂接口来得到绘制图片所需要的资源.本小节将介绍如何通过IWICImagingFactory工厂接口得到这些资源,并使用 ...

  2. asp.net mvc 笔记一

    webapi controller 中 action 名称 不能与 View controller  中的 action 名称相同,否则 Url.Action("actionName&quo ...

  3. POJ 3436 ACM Computer Factory 最大流,拆点 难度:1

    题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...

  4. day04 列表

    今天主要学习了 列表 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查 ...

  5. JAVA设计模式(二)工厂模式

    在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一 ...

  6. C++面向对象实现封装线程池

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  7. 7.9 C++ STL算法

    参考:http://www.weixueyuan.net/view/6406.html 总结: STL提供了大量操作容器的算法,这些算法大致可以分为:排序.搜索.集合运算.数值处理和拷贝等,这些算法的 ...

  8. python三目运算符

    python 可通过 if 语句来实现三目运算符的功能,因此可以近似地把这种if语句当成三目运算符.作为三目运算符的 if 语句的语法格式如下: True_statements if expressi ...

  9. C++11智能指针 share_ptr,unique_ptr,weak_ptr用法

    0x01  智能指针简介  所谓智能指针(smart pointer)就是智能/自动化的管理指针所指向的动态资源的释放.它是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动 ...

  10. 浅议APC

    0x01  APC中断请求级别   在Intel x86体系结构中,外部硬件中断是通过处理器上的"中断管脚"或者一个称为"本地APIC(local APIC)" ...