一、rest=framework之解析器

1)解析器作用。

根据提交的数据。只解析某些特定的数据。非法数据不接收,为了系统安全问题

比如解析的数据格式有

有application/json,x-www-form-urlencoded,form-data等格式

默认支持的数据类型

'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'

2)解析器局部配置

定义路由:url(r'^books/', views.Book.as_view()),

视图函数配置

from rest_framework.parsers import JSONParser   # 只能解析json格式
class Book(APIView):
parser_classes = [JSONParser, ] # 如果加上这行只支持json格式,不加都支持
def get(self,request,*args,**kwargs):
return HttpResponse('OK')
def post(self,request):
print(request.data)
return HttpResponse('post')

实例

说明不支持该格式

2)全局配置。在settings.py的最后加入配置,一般实际工作中,都使用json格式

REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
#'rest_framework.parsers.FormParser'
#'rest_framework.parsers.MultiPartParser'
]}

视图函数,则不需要再添加了

3)全局配置+局部配置

解析器查询顺序,先从本地函数==》settings.py配置 ===》系统函数

即某函数需要用多个解析器,则单独配置,就不走全局配置了

 二、rest=framework之认证组件

1)用户登录测试

1.1)先创建用户表

# 认证的表
class User(models.Model):
nid = models.AutoField(primary_key=True)
name= models.CharField(max_length=)
pwd=models.CharField(max_length=,null=True) class UserToken(models.Model):
user = models.OneToOneField(to=User,to_field='nid')
token=models.CharField(max_length=)

用户认证相关表

1.2)定义路由系统

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

1.3)创建视图函数

# 认证组件
import hashlib,time
def get_token(username):
md = hashlib.md5()
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest() class Login(APIView):
def post(self,requeset):
response = MyResponse()
name = requeset.data.get('name')
pwd = requeset.data.get('pwd')
user = models.User.objects.filter(name=name,pwd=pwd).first()
if user:
response.msg='登陆成功'
# 需要生成一个随机字符串
token=get_token(name)
response.token=get_token(name)
# 吧随机字符串保存到数据库
#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)

class Login

1.4)登录测试

2)用户登录之后才能访问数据测试

2.1)查看定义的路由

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

2.2)查看自己定义的序列化组件

from rest_framework import serializers
from app01 import models class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
exclude=['authors']
name = serializers.CharField(error_messages={'required':'该字段必填'})

myserial.py

2.3)创建视图函数

# 认证组件
import hashlib,time
def get_token(username):
md = hashlib.md5()
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest() class Login(APIView):
def post(self,requeset):
response = MyResponse()
name = requeset.data.get('name')
pwd = requeset.data.get('pwd')
user = models.User.objects.filter(name=name,pwd=pwd).first()
if user:
response.msg='登陆成功'
# 需要生成一个随机字符串
token=get_token(name)
response.token=get_token(name)
# 吧随机字符串保存到数据库
#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) from app01 import myserial
class Book(APIView):
def get(self,request):
# 必须登录才能反问数据库
# token = request.GET.get('token')
token = request.query_params.get('token')
ret = models.UserToken.objects.filter(token=token).first()
response = MyResponse()
if ret:
books=models.Book.objects.all()
ret = myserial.BookSer(instance=books,many=True)
response.msg = '查询成功'
response.data=ret.data
else:
response.msg = '没有登录'
response.status=
return JsonResponse(response.get_dic,safe=False)

Class Login and Books

2.4)登录测试

3)抽取验证是否登录功能,测试(减少重复验证登录的代码冗余)

只修改了视图函数的方法

import hashlib,time
def get_token(username):
md = hashlib.md5()
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest() class Login(APIView):
def post(self,requeset):
response = MyResponse()
name = requeset.data.get('name')
pwd = requeset.data.get('pwd')
user = models.User.objects.filter(name=name,pwd=pwd).first()
if user:
response.msg='登陆成功'
token=get_token(name)
response.token=get_token(name)
ret = models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
else:
response.msg='用户名或密码错误'
response.status=
return JsonResponse(response.get_dic) from rest_framework.exceptions import AuthenticationFailed
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 app01 import myserial
class Book(APIView):
authentication_classes = [myAuthen,]
def get(self,request):
response = MyResponse()
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)

3.1)调试模式,打印输出登录的用户,即携带的token

from app01 import myserial
class Book(APIView):
authentication_classes = [myAuthen,]
def get(self,request):
response = MyResponse()
print(request.user.name) # 打印用户
print(request.auth.token) # 携带的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)

3.2)处理 该函数 authenticate_header 内容为pass 的问题。需要继承 BaseAuthentication 才可删除该无用函数

完善认证组件代码

import hashlib,time
def get_token(username):
md = hashlib.md5()
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest() class Login(APIView):
def post(self,requeset):
response = MyResponse()
name = requeset.data.get('name')
pwd = requeset.data.get('pwd')
user = models.User.objects.filter(name=name,pwd=pwd).first()
if user:
response.msg='登陆成功'
token=get_token(name)
response.token=get_token(name)
ret = models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
else:
response.msg='用户名或密码错误'
response.status=
return JsonResponse(response.get_dic) from rest_framework.exceptions import AuthenticationFailed
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
else:
raise AuthenticationFailed('您没有登录') from app01 import myserial
class Book(APIView):
authentication_classes = [myAuthen,]
def get(self,request):
response = MyResponse()
print(request.user.name) # 打印用户
print(request.auth.token) # 携带的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)

3.3)认证组件总结

作用:校验是否登录
首先定义一个类,继承BaseAuthentication,写一个方法authenticate,在方法内部实现认证过程,
认证通过,返回None或者两个对象(user,auth),在视图类的request中可以取出来。这2个对象也可以是任意2个对象 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,]
全局使用:在settings.py中写入
注意:、全局使用时,认证组件不可以放在视图函数内
、写了全局,局部就要删掉
、在登录函数中,也会走认证组件,而登录是不要认证的
需要在登录中添加:authentication_classes = []
class Login(APIView):
authentication_classes = []
def post(self,requeset):
......

全局使用实例

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

token不存数据库方式,请参照

原文链接:https://www.cnblogs.com/liuqingzheng/articles/9766397.html

二、rest=framework之权限组件

作用:校验用户是否有权限访问
因为是在认证通过才执行的,所以可以取出user

创建类

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)

mychoice选择类型

2.1)定义权限组件

# 权限组件
class myPermission():
message = '不是超超级用户,查看不了'
def has_permission(self,request,view):
print(request.user.usertype)
if request.user.usertype !=:
return False
else:
return True

使用和认证组件的方法一样,只是要写在认证组件之后

from app01 import myserial
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) # 携带的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.2)继承权限:from rest_framework.permissions import BasePermission

from rest_framework.permissions import BasePermission
class myPermission(BasePermission):
message = '不是超超级用户,查看不了'
def has_permission(self,request,view):
print(request.user.usertype)
if request.user.usertype !=:
return False
else:
return True

class myPermission

最新文章

  1. NIO及Reactor模式
  2. ModelMapper 中高级使用 java
  3. 五星评分效果 原生js
  4. android service 本地 远程 总结
  5. Autofac IContainer 测试
  6. Android 调试机制
  7. sampler2d
  8. 【mysql的设计与优化专题(2)】数据中设计中的范式与反范式
  9. C++例题2:汉诺塔问题
  10. ARM9嵌入式学习笔记(1)-Linux命令
  11. API和schema开发过程问题汇总
  12. SQL系统函数的使用(实验五)
  13. shell-like program(shell程序的基本实施部分)
  14. MapReduce流量统计
  15. c/c++ linux 进程间通信系列6,使用消息队列(message queue)
  16. Python3:递归实现输出目录下所有的文件
  17. 使用autohotkey修改方向键、回车和启动程序
  18. 线性空间和异或空间(线性基)bzoj4004贪心+高斯消元优秀模板
  19. MySQL底层索引剖析
  20. java文件上传-原始的Servlet方式

热门文章

  1. 代码管理工具libgit2sharp与sharpsvn
  2. CRM 2016 Get IOrganizationService
  3. Vue 封装的noData组件
  4. 解决idea创建Maven项目卡在running tmp archetypexxxtmp
  5. python3基础: 元组tuple、 列表list、 字典dict、集合set。 迭代器、生成器
  6. Centos nginx安装
  7. 为何要使用ViewModel
  8. leetcode64
  9. js 模拟css3 动画
  10. Ado.net之对数据库的增删改查