一、视图

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. windows系统关闭某个端口的服务(以443端口为例子)

    1.查看443被什么服务占用 netstat -ano | findstr 443 查看到443端口被pid为5140的服务占用了 2.去到任务管理器->任务 找到PID为5140的服务,然后停 ...

  2. poj3278_kuagnbin带你飞专题一

    Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 88247   Accepted: 27640 ...

  3. QT下的贪吃蛇

    QT写的贪吃蛇,学习于https://www.devbean.net/2012/12/qt-study-road-2-snake-1/ 建议就学习一下开发思想,开发游戏还是用专门的编译器. 多加了墙, ...

  4. PE、ELF结构图

    PE:https://bbs.pediy.com/thread-203563.htm ELF:https://blog.csdn.net/jiangwei0910410003/article/deta ...

  5. 远程连接ubuntu mysql出现2003错误 cant connect to mysql(转载)

    不多说直接上代码 1.在控制台输入,进入mysql目录下, sudo su //进入root权限 cd /etc/mysql 2.打开my.cnf文件,找到 bind-address = 127.0. ...

  6. 剑指offer——python【第3题】从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 理解 首先要理解链表的概念,链表是由一串串数字首尾相连组成的 解题 # -*- coding:utf-8 -*- # cla ...

  7. PHP(控制语句,随机数,循环语法)

     1.随机数:Math.random():0到1 不包括1 永远取不到2.控制语句if(){} for循环  语法 运行步骤(过程,原理)   1.初始化 2.判断条件 3.变量改变  index:下 ...

  8. Python学习之旅(一)

    Python的简介 Python是一种面向对象的.动态的脚本语言,可用来设计网页和开发后台功能.其创始人Guido van Rossum于1989年圣诞节期间创造了这门语言. (图片来自百度) Pyt ...

  9. [qemu] qemu从源码编译安装

    环境:CentOS7-1804 下载最新的源码: ┬─[tong@T7:~/Src/thirdparty/PACKAGES]─[:: AM] ╰─>$ axel https://download ...

  10. Linux学习5-CentOS安装Python3.6环境和pip3

    前言 centos7 自带有 python,但是却是 python2 版本的 python,如果你想安装个python3怎么办呢? 如果直接删除python2的话,可能会引起其他的问题,因为有些东西是 ...