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)的更多相关文章

  1. DRF(Django REST Framework)框架

    目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py ...

  2. 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用

    写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...

  3. DRF Django REST framework APIView(一)

    什么是REST? REST是一个标准,一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用. 使url更容易理解,让增删改清晰易懂,在前后端分离开发中按照这一规范能加快开发效率,减 ...

  4. 如何更优雅地写Django REST framework

    DRF(Django REST framework)是一个高度封装的框架,这导致想完成一件事情可以通过重写父类函数的方式从DRF的各个层次来写,都能够实现目的. 比如写视图函数,可以用继承APIVie ...

  5. Vue+Django REST framework打造生鲜电商项目

    1-1 课程导学 2-1 Pycharm的安装和简单使用 2-2 MySQL和Navicat的安装和使用 2-3 Windows和Linux下安装Python2和Python3 2-4 虚拟环境的安装 ...

  6. drf 框架

    一. drf简介 drf框架,全程: django-rest framework  ,   rest是插件名字,django插件的名字叫rest,framework是框架的意思 二. 接口 在平时生活 ...

  7. DRF框架之序列化器初体验

    首先,我们需要明白序列化和反序列化的过程指的是什么. 序列化操作:将模型数据 ---> 字典数据 --->JSON数据(响应JSON数据的操作) 反序列化操作:将JSON数据 ---> ...

  8. drf框架--基础

    目录 drf框架 导入 什么是接口 restful接口规范 原生Django实现接口 drf框架 Django CBV 和drf CBV对比 响应渲染模块 请求数据解析模块 响应模块 二次封装Resp ...

  9. Django Rest Framework Serializer的简单使用

    1.RESTful 1.1 定义 REST(Representational State Transfer)与技术无关,代表一种软件架构风格,中文为表征状态转移. 1.2 RESTful API设计 ...

随机推荐

  1. java基础之缓存:session、cookie和cache的区别

    以前实现数据的缓存有很多种方法,有客户端的Cookie,有服务器端的Session和Application. 其中Cookie是保存在客户端的一组数据,主要用来保存用户名等个人信息. Session则 ...

  2. Java 学习笔记之 线程Priority

    线程Priority: 线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务. 设置线程优先级有助于帮助“线程规划器”确定在下一次选择哪个线程来优 ...

  3. 最近学到的Git知识,大厂的Git机制还是很方便的

    本文首发于微信公众号:程序员乔戈里 转载请注明:https://blog.csdn.net/WantFlyDaCheng/article/details/102538508 一.两次的 git com ...

  4. react native ios 上架

    1.申请开发者账号,去苹果开发者中心申请 2.applicationloader 集申请证书.真机调试.发布于一身,避免繁琐的官网申请过程 http://www.applicationloader.n ...

  5. Java的数组的作业11月06日

    动手动脑 实验一:了解for循环得到棋盘结构 (1) 程序: import java.io.*; public class QiPan { //定义一个二维数组来充当棋盘 private String ...

  6. 利用golang优雅的实现单实例

    平时编写代码过程中,经常会遇到对于全局角度只需运行一次的代码,比如全局初始化操作,设计模式中的单例模式.针对单例模式,java中又出现了饿汉模式.懒汉模式,再配合synchronized同步关键字来实 ...

  7. 基于STM32F1与NRF24L01模块的SPI简单通信

    一.前言 1.简介: 本文是基于STM32F1,将数据发送至NRF模块的寄存器,并将数据重新读取,通过串口发送出来的简单SPI单通信. 2.SPI简介: 调过STM8的都已经对SPI有所了解,调法都一 ...

  8. 前端深入之css篇丨2020年前,彻底掌握css动画【animation】

    写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所 ...

  9. Python_函数做字典的值

    当需要用到3个及以上的if...elif...else时就要考虑该方法进行简化 通过将函数名称当做字典的值,利用字典的关键字查询,可以快速定位函数,进行执行 [场景]用户查询信息,输入fn查询,执行对 ...

  10. sqli-labs靶机注入笔记1-10关

    嗯,开始记录sqli-lab的每关笔记,复习一次 1-2关 基于错误的字符串/数字型注入 闭合的符号有区别而已 http://www.sqli-lab.cn/Less-1/?id=1 or 1=1 - ...