一、视图

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. ubuntu中python3安装package

    1.实验环境 Ubuntu16.04x86 + python3.5 ubuntu中同时存在python2.7 和 python3.5 2.pip使用说明 sudo pip install packag ...

  2. 10 windows server 2012R2 发布MVC框架网站注意事项

    1:网站编译完成之后,需要发布,网站中应包括的文件有:文件夹(bin,Views,Content等其他网站中涉及到的文件夹)文件(favicon.ico.Web.config.Global.asax) ...

  3. 【C++类与对象】实验四(二)

    实现画图类 #ifndef GRAPH_H #define GRAPH_H // 类Graph的声明 class Graph { public: Graph(char ch, int n); // 带 ...

  4. mysql 查询排名 返回值拼接的骚操作

    故事背景: 依照原系统的框子搞一个新的系统给其他人使用,因为新的系统配置库依然需要使用原有的表,表中有字段区分新的系统,然后就有了这个很没劲的数据同步. 难点:配置库码表数据的主键之前是自增,后来改造 ...

  5. mui 轮播

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. sql 2005性能调优

    转自:http://www.cnblogs.com/MR_ke/archive/2010/08/25/1807856.html SQL Server在运行一段时间,随着数据的积累,SQL运行效率会逐步 ...

  7. python全栈开发 * 27知识点汇总 * 180710

    27   time  os  sys  模块 time 模块 一.表示时间的三种方式 时间戳(timestamp), 元组(struct_time),格式化时间字符串(Format string) 小 ...

  8. 第k小整数

    题目描述: 现有n个正整数,n≤10000,要求出这n个正整数中的第k个最小整数(相同大小的整数只计算一次),k≤1000,正整数均小于30000. 输入: 第一行为n和k,第二行开始为n个正整数的值 ...

  9. 如何将PDF文件转Word,有什么方法

    PDF文件怎样转换成Word呢?在现在的日常办公中PDF文件和Word文件都是办公必不可少的两种文件格式了.那么当我们在工作中需要对这两种文件进行转换时,我们应该怎样实现呢?下面我们就一起来看一下吧. ...

  10. [ovs] openvswitch 从源码编译安装

    文档:https://docs.openvswitch.org/en/latest/intro/install/general/ 1. yum install autoconf automake li ...