DRF框架(django rest framework)
1,DRF框架?
Django REST framework 框架是一个用于构建Web API 的强大而又灵活的工具。通常简称为DRF框架 或 REST framework。
Django REST framework 可以帮助我们大大提高REST API 的开发速度,目的就是简化代码
2,序列化和反序列化
序列化:将程序中的一个数据结构类型转换为其他格式(字典、JSON、XML等),例 如 Django中的模型类对象转换为字典或JSON字符串,这个转换过程我们称为序列化。
反序列化:将其他格式(字典、JSON、XML等)转换为程序中的数据,例如将JSON字符串或字典转换保存为Django中的模型类对象,这个过程我们称为反序列化
序列化(侠义):将对象转为字典,json
反序列化(侠义):将字典,json转换为对象
3,Django REST framework 的使用:
1,下载安装:pip install djangorestframework
2,settings中进行注册 INSTALL_APPS ‘rest_framework’
3, DRF 框架序列化:只能将对象转换为字典,不能转换为json
4,DRF框架反序列化:数据校验,数据保存(新增和更新)
4,使用序列化器必须先定义序列化器:
序列化器的定义:
class <序列化器类名> (serializer.Serailizers):
字段 = serializers.字段类型(参数)
5,序列化功能:
1,创建序列化器类对象 serializer = 类名(user) (把对象放入类中)
2,获取序列化后的数据 res = serializers.data() print(res)
6,反序列化功能:
1,创建序列化器对象 serializer = 类名(data={xx}) 把前端传入的字典放入其中
2,进行参数校验 serializer.is_valid 返回true 或 false 代表校验成功和失败
3,获取校验失败的错误信息:serializers.errors 如果成功返回的是空字典
4,获取校验后的数据:serializers.validated_data 返回的是校验成功后的有序字典orderdict
7,序列化器使用的总结:
1,无论是序列化还是反序列化都需要创建序列化器对象
serializers = UserSerializer(instance = none,data={})
序列化时,将序列化对象传给intsance
反序列化时,将字典传给data
8,序列化器类的通用参数:
reade_only (该字段只在序列化时使用设为true)
write_only (该字段只在反序列化时使用设为true)
read_only 和 write_only 不指定时为false ,表示序列化和反序列化时都使用
required 只争对反序列化时使用,默认为true,代表反序列化时必须传入该字段参数,
default 设置序列化或反序列化时的默认值
max_length和min_length:设置反序列化时的最大长度和最小长度
max_value和min_value:设置反序列化时的最大值和最小值
9,序列化操作
1,序列化单个对象
book = BookInfo.objects.get(id=1)
serizlizer = BookInfoSerializer(book)
res = serializer.data
2,序列化多个对象
books = BookInfo.objects.all() #Queryset
serializer = BookInfoSerializer(books,many=True)
res = serializer.data
3,关联对象 嵌套序列化
#1,将关联对象序列化为关联对象的主键
hbook = serializer.PrimarykeyRelatedFiled(label = '图书',read_only = true) 或
hbook = serializer.PrimarykeyRelatedFiled(label = '图书',queryset=BookInfo.objects.all()) #2,使用指定的序列化器将关联对象一并序列化
hbook = BookInfoSerializer() #3,将关联对象序列化为关联对象模型类__str__的返回值
hbook = serializer.StringRelatedFiled(lable='图书')
注意:和一个对象关联的对象如果有多个,在进行嵌套序列化字段定义时,需要加 many=true
10 ,反序列化操作 (可以进行校验和保存)校验只能进行数据是否完整,类型是否正确,以及一些选项参数对data中的数据进行校验
1, 补充校验的三种方式:
注意:方式一 :在定义序列化器类外定义一个函数进行校验,在字段后面添加 validators = 函数名 (不常用)
方法二:在定义序列化器类里添加函数,其中函数名必须是 validate_<字段名> (缺点是只能对单个字段进行校验)
方法三 : 在定义序列化器类里添加函数,可以进行多个字段的对比,函数名必须是 validata
2,保存数据:
前提:必须校验通过ser.is_valid()
使用:serializer.save() 内部可能会调用序列化器类的create或update方法,(如果序列化器类继承serializer.Serializer,需要重写这两个方法,该父类为实现,如果继承serializer.ModelSerializer,父类已经实现)
创建序列化器对象时,如果只传入instance,save()方法被调用,否则create()方法被调用(create方法调用时instance和data参数都要传入)
3,ModelSerializer类的使用
使用:序列化器需要对应是Django的模型类
特点:自动生成序列化器类中的字段
默认已经实现create和update方法
11,APIView视图类
APIView是View的子类,
区别:1,请求对象:Request
request.data :包含解析之后的请求体中的数据,相当于之前的request.POST | request.body | request.FILEs
request.query_params : 包含了解析之后的查询字符串中的数据 QueryDict
2,响应对象:response(原始的响应数据)
根据客服端请求头中Accept自动转换为对应的格式,不需要指定,直接返回res.data ,默认返回json
3, 自动处理APIException的子类异常和Http404
4,其他权限,认证,权限,限流 (后面细说)
12,GenericAPIView视图类
class BookListView(GenericAPIView):
#指定视图所使用的序列化器类
serializer_class = BookInfoSerializer #名字必须是serializer_class,父类已经定义,但为None,需要自己指定 #指定视图所使用的查询集
queryset = BookInfo.objects.all() #名字也是必须是queryset,和上面一样,可以到源码进行查看
继承genericAPIView后可以调用下面的方法:
get_serializer_class : 获取指定的序列化器类
get_serializer :获取指定的序列化器类对象
get_queryset:获取指定的查寻集
get_object : 从指定查询集查询一个对象进行返回,默认根据url地址提取的pk进行查询,所以不需要传递参数pk,该函数会制动从url中进行匹配
注意:使用get_serializer_class 和get_serializer 之前必须先指定serializer_class
使用get_queryset和get_object必须先指定queryset 属性
2,GenericAPIView 和APIView 的区别:继承自APIView
1) 增加操作序列化器相关属性和方法
2) 增加数据库查询相关属性和方法
3) 过滤,排序,分页 (后面细说)
3,GenericAPIView 案例:(增,删,改,查)
#/books/
class BookListView(GenericApIview):
#指定视图使用的序列化器类
serializer_class = BookInfoSerializer() #序列化器类 #指定查询集
queryset = BookInfo.objects.all() #查询所有书籍
def get(self,request):
books = self.get_queryset() # Queryset:查询集
#将所有图书数据通过json进行返回
ser = self.get_serializer(books,many=true) #多个加many=true return Response(ser.data) #ser.data 将序列化后的数据进行返回 #新增书籍
def post(self,request):
#校验前端传入的数据
ser = self.get_serializer(data=request.data)
ser.is_valid(raise_exception=true) #保存数据
ser.save() #调用序列化器类中的create方法 #将新增的图书进行返回
return Response(ser.data,status=status.HTTP_201_CREATE)
class BookDetailView(GenericAPIView):
serializer_class = BookInfoSerializer()
queryset = BookInfo.objects.all() #查找指定图书
def get(self,request,pk):
book = self.get_object() #不用传参数,改函数会自动在url中查找pk的值 ser = self.get_serializer(book) return Response(ser.data) #修改指定图书
def put(self,request,pk):
book = self.get_object() #参数校验
ser = self.get_serializer(book,data=request.data)
ser.is_valid(raise_exception=true)
#校验通过保存数据
ser.save()
return Response(res.data) #删除指定图书
def delete(self,request,pk):
book = self.get_object()
book.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
13 , Mixin扩展类
继承object,不能单独使用,需要配合GenericAPIView来进行使用
DRF框架提供5个Mixin扩展类,就是对上面五个函数进行封装:
# 自己封装Mixin扩展类
class MyListModelMixin(object):
def list(self, request, *args, **kwargs):
"""封装获取一组数据的通用代码流程"""
query_set = self.get_queryset() # QuerySet:查询集
serializer = self.get_serializer(query_set, many=True)
return Response(serializer.data) class MyCreateModelMixin(object):
def create(self, request, *args, **kwargs):
"""封装新增一条数据通用代码流程"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save() # 调用序列化器类中的create
return Response(serializer.data, status=status.HTTP_201_CREATED) # /books/
class BookListView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
# 指定视图使用的序列化器类
serializer_class = BookInfoSerializer
# 指定视图使用的查询集
queryset = BookInfo.objects.all() # serializer_class = HeroInfoSerializer
# queryset = HeroInfo.objects.all() def get(self, request):
return self.list(request) def post(self, request):
return self.create(request) class MyRetrieveModelMixin(object):
def retrieve(self, request, *args, **kwargs):
"""封装获取指定数据通用代码流程"""
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data) # obj = MyRetrieveModelMixin()
# obj.retrieve() class MyUpdateModelMixin(object):
def update(self, request, *args, **kwargs):
"""封装修改指定数据通用代码流程"""
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save() # 调用序列化器类中的update
return Response(serializer.data) class MyDestroyModelMixin(object):
def destroy(self, request, *args, **kwargs):
"""封装删除指定数据的通用代码流程"""
instance = self.get_object()
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT) # 系统封装的
# /books/(?P<pk>\d+)/
# /books/100/
class BookDetailView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
serializer_class = BookInfoSerializer
queryset = BookInfo.objects.all() def get(self, request, pk):
return self.retrieve(request, pk) def put(self, request, pk):
return self.update(request, pk) def delete(self, request, pk):
return self.destroy(request, pk)
14,子类视图:
继承了GenericAPIView和对应的Mixin扩展类,而且还提供了对应的请求处理函数(get,post)
class BookListView(ListAPIView):
serializer_class = BookInfoSerializer
queryset = BookInfo.objects.all()
15,视图集:
概念:将一组相关的API接口放在同一个类中,这个类就叫视图集。
基本使用:
1,继承父类ViewSet
2, 视图集中处理方法不以请求方发命名(get,..),而是以对应的操作命名:list,create,retrieve,update,destroy
3, 进行url地址配置时,需要指明请求方式,请求url地址时对应的处理方法
视图集父类:
ViewSet(继承ViewSetMixin和APIView)
GenericViewSet(继承ViewSetMixin和GenericAPIView) 可以配合Mixin扩展类来提供对应的处理函数
ModelViewSet(继承GenericviewSet和5个Mixin扩展类) 常用
ReadOnlymodelViewSet(继承GenericViewSet和2个Mixin扩展类) (ListModelMixin和RetievemodelMixin)
视图集添加额外的API方法即可,注意不要和其他API方法名有冲突
* 直接在视图集中添加API方法即可,注意不要和其他API方法名有冲突
* 添加之后需要进行url地址配置
16,路由router
作用:动态生成视图集中API接口的url 配置项
使用:
lookup_value_regex:
设置router生成路由时,从url中提取pk参数对应的正则表达式
视图集中额外API接口配置项生成:
需要添加action装饰器(导入 from rest_framework.decorators import action)
注意:detail = true或false,看是否需要从url中提取PK,需要就设置为true
defaultRouter和SimpleRouter区别:
1,DefaultRouter多生成一个根路径/配置项
2,每个配置项都可以直接根据.json,返回json数据
17 ,认证 | 权限 | 限流
1,认证:
DRF框架默认全局支持两种认证方法:session认证和基本认证
可以修改全局的认证方式:
REST_FRAMEWORK = {
# 修改全局认证方式
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', # 仅支持session认证
),
}
# 指定视图自己的认证方式,此处仅支持session认证
authentication_classes = [SessionAuthentication]
权限:
1,DRF框架默认全局权限设置为:AllowAny,代表允许所有人访问
2,可以修改全局的权限控制方式
REST_FRAMEWORK = {
# 修改全局权限控制方式
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated', # 允许认证用户
)
}
指定视图自己的权限控制方式,此处代表只有认证过的用户才能访问本视图集中的接口
permission_classes = [IsAuthenticated]
3,自定义权限控制类
class MyPermission(BasePermission):
def has_permission(self, request, view):
"""判断用户对使用这个权限控制类的视图中的API接口是否有访问权限"""
return True def has_object_permission(self, request, view, obj):
"""判断用户对使用这个权限控制类中视图中某个对象是否有访问权限"""
# get_object:
# 需求:id为1或3的对象用户可以访问,其他的对象不允许访问
if obj.id in (1, 3):
return True
return False
限流:限制用户访问接口的频率
1,分别限流
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
# 针对未登录(匿名)用户的限流控制类
'rest_framework.throttling.AnonRateThrottle',
# 针对登录(认证)用户的限流控制类
'rest_framework.throttling.UserRateThrottle'
),
# 指定限流频次
'DEFAULT_THROTTLE_RATES': {
# 认证用户的限流频次
'user': '5/minute',
# 匿名用户的限流频次
'anon': '3/minute',
},
}
统一限流:
REST_FRAMEWORK = {
# 针对匿名用户和认证用户进行统一的限流控制
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
), # 指定限流频次选择项
'DEFAULT_THROTTLE_RATES': {
'upload': '3/minute',
'contacts': '5/minute'
},
}
统一限流,还需要在视图中通过属性throttle_scope指定限流选项
18 ,过滤 | 排序 | 分页
过滤:
1,安装:pip install django-filter
2,注册子应用,添加过滤配置
3,在视图中通过filter_fields属性指定过滤字段
排序:
在视图中排序设置:(前端在查询字符串中指定排序字段,http://xxxx.com/?ordering=id)
分页:
设置全局分页类
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 5 # 页容量
}
注意:设置全局分页类之后,默认情况下凡是使用ListModelMixin中的List返回数据的API,都会使用全局分页类进行分页,如果要取消,可以在该视图中设置:
pagination_class = None
自定义分页类;
# ?page=<页码>&pagesize=<页容量>
class StandardResultPagination(PageNumberPagination):
# 默认分页页容量
page_size = 3
# 指定页容量参数的名称
page_size_query_param = 'pagesize'
# 分页最大页容量
max_page_size = 5
注意:自定义分页类可以设置为全局分页类或指定视图自己使用的分页类
19,异常处理
只要继承了APIView或者它的子类,视图中的处理异常:APIException子类异常或HTTP404,DRF框架都可以自动处理
自定义异常处理函数:
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from rest_framework import status
from django.db import DatabaseError def exception_handler(exc, context):
# 调用DRF框架默认异常处理函数
response = drf_exception_handler(exc, context) if response is None:
# DRF框架不能处理此异常,自己处理:DatabaseError
if isinstance(exc, DatabaseError):
response = Response({'detail': '数据库错误!!!'}, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response
复制代码
修改EXCEPTION_HANDLER配置项
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'booktest.utils.exceptions.exception_handler'
}
DRF框架(django rest framework)的更多相关文章
- DRF(Django REST Framework)框架
目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py ...
- 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...
- DRF Django REST framework APIView(一)
什么是REST? REST是一个标准,一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用. 使url更容易理解,让增删改清晰易懂,在前后端分离开发中按照这一规范能加快开发效率,减 ...
- 如何更优雅地写Django REST framework
DRF(Django REST framework)是一个高度封装的框架,这导致想完成一件事情可以通过重写父类函数的方式从DRF的各个层次来写,都能够实现目的. 比如写视图函数,可以用继承APIVie ...
- Vue+Django REST framework打造生鲜电商项目
1-1 课程导学 2-1 Pycharm的安装和简单使用 2-2 MySQL和Navicat的安装和使用 2-3 Windows和Linux下安装Python2和Python3 2-4 虚拟环境的安装 ...
- drf 框架
一. drf简介 drf框架,全程: django-rest framework , rest是插件名字,django插件的名字叫rest,framework是框架的意思 二. 接口 在平时生活 ...
- DRF框架之序列化器初体验
首先,我们需要明白序列化和反序列化的过程指的是什么. 序列化操作:将模型数据 ---> 字典数据 --->JSON数据(响应JSON数据的操作) 反序列化操作:将JSON数据 ---> ...
- drf框架--基础
目录 drf框架 导入 什么是接口 restful接口规范 原生Django实现接口 drf框架 Django CBV 和drf CBV对比 响应渲染模块 请求数据解析模块 响应模块 二次封装Resp ...
- Django Rest Framework Serializer的简单使用
1.RESTful 1.1 定义 REST(Representational State Transfer)与技术无关,代表一种软件架构风格,中文为表征状态转移. 1.2 RESTful API设计 ...
随机推荐
- java基础之缓存:session、cookie和cache的区别
以前实现数据的缓存有很多种方法,有客户端的Cookie,有服务器端的Session和Application. 其中Cookie是保存在客户端的一组数据,主要用来保存用户名等个人信息. Session则 ...
- Java 学习笔记之 线程Priority
线程Priority: 线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务. 设置线程优先级有助于帮助“线程规划器”确定在下一次选择哪个线程来优 ...
- 最近学到的Git知识,大厂的Git机制还是很方便的
本文首发于微信公众号:程序员乔戈里 转载请注明:https://blog.csdn.net/WantFlyDaCheng/article/details/102538508 一.两次的 git com ...
- react native ios 上架
1.申请开发者账号,去苹果开发者中心申请 2.applicationloader 集申请证书.真机调试.发布于一身,避免繁琐的官网申请过程 http://www.applicationloader.n ...
- Java的数组的作业11月06日
动手动脑 实验一:了解for循环得到棋盘结构 (1) 程序: import java.io.*; public class QiPan { //定义一个二维数组来充当棋盘 private String ...
- 利用golang优雅的实现单实例
平时编写代码过程中,经常会遇到对于全局角度只需运行一次的代码,比如全局初始化操作,设计模式中的单例模式.针对单例模式,java中又出现了饿汉模式.懒汉模式,再配合synchronized同步关键字来实 ...
- 基于STM32F1与NRF24L01模块的SPI简单通信
一.前言 1.简介: 本文是基于STM32F1,将数据发送至NRF模块的寄存器,并将数据重新读取,通过串口发送出来的简单SPI单通信. 2.SPI简介: 调过STM8的都已经对SPI有所了解,调法都一 ...
- 前端深入之css篇丨2020年前,彻底掌握css动画【animation】
写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所 ...
- Python_函数做字典的值
当需要用到3个及以上的if...elif...else时就要考虑该方法进行简化 通过将函数名称当做字典的值,利用字典的关键字查询,可以快速定位函数,进行执行 [场景]用户查询信息,输入fn查询,执行对 ...
- sqli-labs靶机注入笔记1-10关
嗯,开始记录sqli-lab的每关笔记,复习一次 1-2关 基于错误的字符串/数字型注入 闭合的符号有区别而已 http://www.sqli-lab.cn/Less-1/?id=1 or 1=1 - ...