一、视图

1.基本视图

#基本视图
#抽取基类
from rest_framework.response import Response
from rest_framework.views import APIView
from app1.models import *
from app1.Myserializer import BookSerializer
from app1.Myserializer import PublishSerializer
class List():
def list(self,request,*args,**kwargs):
response = {'status':100,'msg':'查询成功'}
g = self.model
g_ser = self.model_ser(instance=g,many=True)
response['data'] = g_ser.data
return Response(response) class Create():
def create(self,request,*args,**kwargs):
response = {'status': 100, 'msg': '新增成功'}
try:
p_ser = self.model_ser(data=request.data)
if p_ser.is_valid():
p_ser.save()
response['data'] = p_ser.data
else:
response['msg'] = p_ser.errors
except Exception as e:
response['msg'] = str(e)
return Response(response) #图书查询,新增
class BooksView(List,Create,APIView):
model = Book.objects.all()
model_ser = BookSerializer
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs) def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs) #出版社查询,新增
class PublishView(List,Create,APIView):
model = Publish.objects.all()
model_ser = PublishSerializer
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs) def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs)

2.mixin类和generice类编写视图

from app1.models import *
from app1.Myserializer import BookSerializer
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
from rest_framework.generics import GenericAPIView
#ListModelMixin:获取所有 CreateModelMixin:新增 RetrieveModelMixin:获取单本 UpdateModelMixin:更新 DestroyModelMixin:删除
class BooksView(ListModelMixin,CreateModelMixin,GenericAPIView):
serializer_class = BookSerializer
queryset = Book.objects.all()
#获取所有图书
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs) #新增图书
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs) class BookView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView):
serializer_class = BookSerializer
queryset = Book.objects.all() #获取单本
def get(self,request,*args,**kwargs):
return self.retrieve(request,*args,**kwargs) #更新图书
def put(self, request, *args, **kwargs):
return self.update(request,*args,**kwargs) #删除图书
def delete(self,request,*args,**kwargs):
return self.destroy(request,*args,**kwargs)

3.使用generics 下ListCreateAPIView,RetrieveUpdateDestroyAPIView

from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
#获取所有和新增图书
class BooksView(ListCreateAPIView):
serializer_class = BookSerializer
queryset = Book.objects.all() #查询单个图书,更新,删除
class BookView(RetrieveUpdateDestroyAPIView):
serializer_class = BookSerializer
queryset = Book.objects.all()

4.使用ModelViewSet,将两个视图类写成一个类,五种请求:get,get,post,delete

from app1.models import *
from app1.Myserializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BooksView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer #路由层路由配置
url(r'^books/$', views.BooksView.as_view({'get':'list','post':'create'})),
url(r'^books/(?P<pk>\d+)$',\
views.BooksView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),

5.ViewSetMixin的使用,重写了as_view方法

要用ViewSetMixin,路由跟之前写法不一样了
url(r'^test', views.Publish.as_view({'get':'aa'})), 视图类中
from rest_framework.viewsets import ViewSetMixin
class Publish(ViewSetMixin,APIView):
def aa(self,request):
return HttpResponse('aa')

二、认证组件

-什么是认证?是用来干什么的?
校验用户是否是我的登录用户 -drf源码中找,认证如何实现的
-APIView的dispach方法---》self.initial(request, *args, **kwargs)----》400行self.perform_authentication(request)---》APIView的perform_authentication(request)----》request.user(request是新的request)---->去Request类中找user,执行--->self._authenticate()(self是新的reqeust对象)---->Request类的_authenticate(self)方法

使用认证功能

'''
1.①写一个认证类MyAuthentication,继承BaseAuthentication
②类的内部重写authenticate方法
③在authenticate方法中写认证逻辑,认证通过,返回None,认证不通过,抛异常
④校验通过,也可以返回当前登录的用户和auth,这样操作,在视图类中,可以通过request.user,获取到当前登录的用户
⑤一旦返回了值,后续的认证类就不会再走了
''' '''
2.authentication_classes查找顺序(认证类的查找顺序):
①先在自己类当中找:authentication_classes=[MyAuthentication]
②如果自己当中没有配置,去去项目settings.py中去找
③如果项目setting中没有配置,去drf的setting中找
''' '''
3.最终在认证中的使用
局部使用:
-在视图类中配置:authentication_classes=[MyAuthentication]
全局使用:
-在setting.py中配置:
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':['app1.MyAuth.MyAuthentication']
}
全局使用了局部禁用:
-在视图类中配置:authentication_classes=[]
''' from rest_framework.response import Response
from app1.models import *
from rest_framework.views import APIView
import uuid
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication class MyAuthentication(BaseAuthentication):
def authenticate(self,request):
#认证相关的东西
#校验请求是否携带正确的token
#取出token
token = request.GET.get('token')
#校验该次请求是否携带正确的token
ret = UserToken.objects.filter(token=token).first()
if ret:
#正常通过认证的用户
return ret.user,ret
else:
#没有登录或非法用户
raise AuthenticationFailed('您没有通过认证') class BooksView(APIView):
#某个视图类需要登陆后才能查看,只需要在视图类加入下面代码
authentication_classes=[MyAuthentication]
def get(self,request):
return Response('ok') class Login(APIView):
def post(self,request):
response={'status':100,'msg':None}
name = request.data.get('name')
pwd = request.data.get('pwd') #去数据库校验数据是否存在
user = User.objects.filter(name=name,pwd=pwd).first()
if user:
#正常用户登录成功 #返回唯一的随机字符串
token = uuid.uuid4() #生成随机的字符串存到数据库中,如果存在更新token,不存在新增一条
# 根据user去查询,如果查到数据,更新defaults中的数据,如果查不到,新增一条数据
ret = UserToken.objects.update_or_create(user=user,defaults={'token':token})
response['msg'] = '登录成功'
response['token'] = token
else:
response['status'] = 101
response['msg'] = '账号或密码错误'
return Response(response) #请求
#http://127.0.0.1:8000/books/?token=735061c3-733d-463d-8158-ccfa2e13f539
#token匹配成功就会得到图书信息,否则返回没有通过认证 #加了 authentication_classes=[MyAuthentication] 这句代码,直接访问http://127.0.0.1:8000/books/ 会返回没有通过认证

三、权限组件

'''
权限是什么?
比如只有超级用户可以访问books这个接口
使用:
①写一个权限类MyPermissions,继承BasePermission
②类的内部重写has_permission方法
③在has_permission方法内部写权限逻辑,通过返回True,失败返回False
'''
user表
class User(models.Model):
name=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
choice=((1,'超级用户'),(2,'普通用户'),(3,'穷逼用户'))
type = models.IntegerField(choices=choice,null=True) from rest_framework.permissions import BasePermission
class MyPermissions(BasePermission):
def has_permission(self, request, view):
#是否为超级用户
if request.user.type == 1:
#如何取type对应的文字 get_字段名_display()
user_type = request.user.get_type_display()
#超级用户校验通过返回True
return True
else:
#校验失败返回False
return False '''
最终的使用
局部使用:
-在视图类中配置:permission_classes=[MyPermissions]
全局使用:
-在settings.py中配置:
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':['app1.MyAuth.MyPermissions']
}
全局使用了局部禁用:
-在视图类中配置:permission_classes=[]

四、频率组件

'''
频率是什么?
-同一段时间内,只能访问多少次
'''
频率组件的使用:
①写一个频率类Mythrottling,继承SimpleRetaThrottle
②重写get_cache_key方法,方法返回什么,频率组件就以什么做限制(比如返回ip,就以ip做限制.返回user_id,就会以用户id做限制)
from rest_framework.throttling import SimpleRateThrottle
class MyThrottling(SimpleRateThrottle):
scope = 'xxx'
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR') #返回客户端ip地址 ③在setings.py中配置:
'DEFAULT_THROTTLE_CLASSES':{
'xxx:'3/m' #每分钟三次
} ④局部使用:
-在视图类中配置:throttle_classes=[MyThrottling]
全局使用:
-在settings.py中配置
REST_FRAMEWORK={
'DEFAULT_THROTTLE_CLASSES':['app1.MyAuth.MyThrottling']
}
全局使用了局部禁用:
-在视图类中配置:throttle_classes=[]

自定义频率控制类

'''
频率控制的逻辑
某个ip地址一分钟只能访问三次
{ip地址1:[第三次访问的时间,第二次访问的时间,第一次访问的时间],ip地址2:[]}
(1)取出访问者ip
(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
(3)循环判断当前ip的时间列表,有值,并且当前时间减去列表的最后一个时间大于60s,把列表中最后一个数用pop去掉,这样列表中只有60s以内的访问时间,
(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
'''
from rest_framework.throttling import BaseThrottle
class MyThrottling(BaseThrottle):
#访问者ip字典
VISIT_RECORD = {}
def __init__(self):
#访问者ip对应的时间列表
self.history=None
def allow_request(self, request, view):
#(1)取出访问者ip
ip = request.META.get('REMOTE_ADDR')
#获取当前时间
import time
ctime = time.time()
#(2)判断当前ip不在访问字典里,添加进去,并且直接返回True, 表示第一次访问,在字典里,继续往下走
if ip not in self.VISIT_RECORD:
self.VISIT_RECORD[ip]=[ctime,]
return True
#获取当前访问者的时间列表self.history
self.history = self.VISIT_RECORD.get(ip)
#(3)循环判断当前ip的时间列表,有值,并且当前时间减去列表的最后一个时间大于60s,把列表中最后一个数据用pop去掉,这样列表中只有60s以内的访问时间
while self.history and ctime-self.history[-1] > 60:
self.history.pop()
#(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败 if len(self.history) < 3:
self.history.insert(0,ctime)
return True
else:
return False #还要等待的时间
def wait(self):
import time
ctime = time.time()
return 60 - (ctime-self.history[-1])

rest_framework视图和组件的更多相关文章

  1. Django的rest_framework的分页组件源码分析

    前言: 分页大家应该都很清楚,今天我来给大家做一下Django的rest_framework的分页组件的分析:我的讲解的思路是这样的,分别使用APIview的视图类和基于ModelViewSet的视图 ...

  2. Django的rest_framework的权限组件和频率组件源码分析

    前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...

  3. Django之REST_framework 框架基本组件使用

    快速实例 快速实例: 点击查看官方文档 阅读推荐:点击查看 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如j ...

  4. rest_framework之序列化组件

    什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有form组件帮我们去做数据校验 我们有模板语法,从数据库取出的queryset对象不需要人为去转格式 当我们写前后端分离项 ...

  5. 关于Android界面编程与视图(View)组件

    UI组件--------------->android.widget.* View组件------------->android.view.* 视图(View)组件 所有UI组件都是建立在 ...

  6. rest_framework解析器组件源码流程

    rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...

  7. Android零基础入门第54节:视图切换组件ViewSwitcher

    原文:Android零基础入门第54节:视图切换组件ViewSwitcher 前面三期学习了ProgressBar系列组件,那本期开始一起来学习ViewAnimator组件. 一.ViewAnimat ...

  8. DRF(3) - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

    一.序列化组件 基于上篇随笔的表结构,通过序列化组件的ModelSerializer设计如下三个接口: GET 127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{} PU ...

  9. DRF - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

    一.序列化组件 基于上篇随笔的表结构 , 通过序列化组件的ModelSerializer设计如下三个接口 : GET 127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{} ...

随机推荐

  1. 死锁的原因及解决办法RLock递归锁

    死锁 说到死锁,可以讲一个科学家吃面的问题: 有几个科学家在一张桌子旁,桌子上只有一把筷子和一碗面,我们将面和筷子都加锁.这是可能会导致一个科学家抢到面,另一个科学家抢到筷子,这是就全部阻塞了,这就是 ...

  2. linux的基本操作(磁盘管理)

    磁盘管理 [查看磁盘或者目录的容量 df 和 du] df 查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的 df常用参数有 –i -h -k –m等 -i 使用 ...

  3. Oracle 创建表 Create Table...

    一.创建表 主键约束primary key 约束条件,唯一且非空,一个表中只能有一个主键:有多个字段联合作为主键时,合在一起唯一标识记录,叫做联合主键. 外键约束 foreign key 受另外一张表 ...

  4. css的小知识

    ---恢复内容开始--- 1.当你发现在制作页面时出现滚动条就需要一个去除滚动条的属性 overflow:hidden:           overflow-x:hidden:水平超出隐藏 2.  ...

  5. 谁考了第k名

    题目描述: 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩. 输入: 第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k ...

  6. LINUX常用命令 --- 权限篇

    linux常用命令 linux用户权限相关 root 用户    相当于群主    超级用户 sudo命令   相当于群管理员 普通用户    群成员 查看用户id信息      使用linux    ...

  7. 2018-2019-2 20165330《网络对抗技术》Exp5 MSF基础应用

    目录 基础问题 相关知识 实验目的 实验内容 实验步骤 离实战还缺些什么技术或步骤? 实验总结与体会 实验目的 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路 返回目 ...

  8. laravel队列使用

    1.修改.env中queue_driver = databases 2.php artisan queue:table 在database 目录下migrations里面有对应的表 3.执行迁移文件 ...

  9. Java如何获取图片验证码保存

    举例网站:https://my.1hai.cn/Login/?url=http://www.1hai.cn/ 一.场景:出于安全性考虑,越来越多的Web平台登录都会增加图形验证码(图片),或者短信验证 ...

  10. python基础之 编码进阶,文件操作和深浅copy

    1.编码的进阶 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码.即先将其他编码的字符串解码(decode)成unicode,再从unic ...