一、Request和Response

  1. Request

REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的**Request**类的对象。

REST framework 提供了**Parser**解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典对象保存到**Request**对象中。

#DRF中的请求导入方式
from rest_framework.request import Request
Request.data #请求数据
Request.query_params====>Django.GET

常用属性

1).data

`request.data` 返回解析之后的请求体数据。类似于Django中标准的`request.POST`和 `request.FILES`属性,但提供如下特性:

- 包含了解析之后的文件和非文件数据

- 包含了对POST、PUT、PATCH请求方式解析后的数据

- 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据

2).query_params

`request.query_params`与Django标准的`request.GET`相同,只是更换了更正确的名称而已。

2. Response

REST framework提供了一个响应类`Response`,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。

REST framework提供了`Renderer` 渲染器,用来根据请求头中的`Accept`(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。

#DRF中的响应导入方式
from rest_framework.response import Response
Response(data=Response.data,status=200,template_name=None,headers=None,content_type=None)

`data`数据不要是render处理之后的数据,只需传递python的内建类型数据即可,REST framework会使用`renderer`渲染器处理`data`。

`data`不能是复杂结构的数据,如Django的模型类对象,对于这样的数据我们可以使用`Serializer`序列化器序列化处理后(转为了Python字典类型)再传递给`data`参数。

参数说明:

- `data`: 为响应准备的序列化处理后的数据;

- `status`: 状态码,默认200;

- `template_name`: 模板名称,如果使用`HTMLRenderer` 时需指明;

- `headers`: 用于存放响应头信息的字典;

- `content_type`: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。

常用属性:

1).data传给response对象的序列化后,但尚未render处理的数据

2).status_code状态码的数字

3).content经过render处理后的响应数据

  • 视图

2.1 两个基类

1) APIView

from rest_framework.views import APIView

APIView是REST framework提供的所有视图的基类,继承自Django的View父类。

APIView与View的不同之处在于:

(1)传入到视图方法中的是REST framework的`Request`对象,而不是Django的`HttpRequeset`对象;

(2)视图方法可以返回REST framework的`Response`对象,视图会为响应数据设置(render)符合前端要求的格式;

(3)任何`APIException`异常都会被捕获到,并且处理成合适的响应信息;

(4)在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

支持定义的属性:

authentication_classes 列表或元祖,身份认证类

permissoin_classes 列表或元祖,权限检查类

throttle_classes 列表或元祖,流量控制类

在APIView中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。

使用APIView实现增删改查所有图书:

views.py文件

################1.APIView视图###############################
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
# from django.views import View
# 使用APIView实现增删改查所有图书:
#继承APIView
class BookListAPIView(APIView):"""列表视图"""def get(self,request):#1.查询所有的图书all=BookInfo.objects.all()# 2.序列化数据,把模型对象转换成字典# instance 默认参数# many=True 显示多个数据#构造序列对象ser=BookInfoSerializer(instance=all,many=True)# print(ser.data)# response =Response(ser.data)# print(response.data) #响应对象未渲染处理的数据# print(response.content) # 处理后要响应给前端的数据# return response#响应return  Response(ser.data)passdef post(self,request):'''添加数据'''#获取前端传入请求参数data=request.data#使用序列化器进行反序列哈ser=BookInfoSerializer(data=data)#校验 raise_exception显示错误消息ser.is_valid(raise_exception=True)#保存ser.save()#响应return Response(ser.data,status=status.HTTP_201_CREATED)pass
#继承APIView
class BookDataAPIView(APIView):'''详情视图 '''def get(self, request,pk):'''查询指定的模型对象=>必须指定id'''try:book=BookInfo.objects.get(id=pk)except  BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)# 构造序列化器对象ser =BookInfoSerializer(instance=book)# 响应return Response(ser.data)passdef put(self,request,pk):'''更新指定的模型对象=>必须指定id,需要校验'''try:book=BookInfo.objects.get(id=pk)except BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)# 构造序列化器对象,获取前端传入的请求体数据ser = BookInfoSerializer(instance=book,data=request.data)#校验ser.is_valid(raise_exception=True)#保存ser.save()#响应return Response(ser.data)passdef delete(self,request,pk):'''删除指定的模型对象=>必须指定id''''''查询指定的模型对象=>必须指定id'''try:book = BookInfo.objects.get(id=pk)except  BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)#删除book.delete()return Response(status=status.HTTP_204_NO_CONTENT)

urls.py文件

 #APIView视图path('books/',views.BookListAPIView.as_view()),  #查询所有的图书数据, 类视图;注意:as_view()re_path(r'^books/(?P<pk>\d+)/$',views.BookDataAPIView.as_view()) #查询详情数据, 类视图;注意:as_view() 必须有()
]

效果:

删除之后,再查看:

2) GenericAPIView

from rest_framework.generics import GenericAPIView

继承自APIVIew,增加了对于列表视图和详情视图可能用到的通用支持方法。通常使用时,可搭配一个或多个Mixin扩展类。

源码如下:

支持定义的属性:

(1) 列表视图与详情视图通用:

queryset 列表视图的查询集

serializer_class 视图使用的序列化器

(2) 列表视图使用:

pagination_class 分页控制类

filter_backends 过滤控制后端

(3) 详情页视图使用:

lookup_field 查询单一数据库对象时使用的条件字段,默认为'`pk`'

lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同

常用方法:

  1. get_queryset(self)  返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回`queryset`属性,可以重写
  2. get_serializer(self, *args, **kwargs) 返回序列化器对象,被其他视图或扩展类使用,如果我们在视图中想要获取序列化器对象,可以直接调用此方法。
  3. get_object(self) 返回详情视图所需的模型类数据对象,默认使用`lookup_field`参数来过滤queryset。 在试图中可以调用该方法获取详情信息的模型类对象。

使用GenericAPIView实现增删改查所有图书:

views.py文件

################2.GenericAPIView视图###############################
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):'''列表查询'''# 指定查询集'数据来源'queryset =BookInfo.objects.all()# 指定序列化器类serializer_class =BookInfoSerializer#查询方法def get(self,request):# 获取数据集find=self.get_queryset()# 返回序列化器对象ser=self.get_serializer(find,many=True)return Response(ser.data)def post(self, request):'''添加数据'''# 获取前端传入请求参数data = request.data# 使用序列化器进行反序列哈ser = BookInfoSerializer(data=data)# 校验 raise_exception显示错误消息ser.is_valid(raise_exception=True)# 保存ser.save()# 响应return Response(ser.data, status=status.HTTP_201_CREATED)class BookDataGenericAPIView(GenericAPIView):'''详情视图'''queryset = BookInfo.objects.all()serializer_class = BookInfoSerializerdef get(self,request,pk):'''根据id查询数据'''book=self.get_object()ser=self.get_serializer(book)return Response(ser.data)passdef put(self, request, pk):'''根据id更新数据'''book = self.get_object()#请求数据ser = self.get_serializer(book,request.data)#校验ser.is_valid(raise_exception=True)#保存ser.save()return Response(ser.data)passdef delete(self, request, pk):'''根据id删除数据,有可能发生异常'''try:book = self.get_object()except BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)# 删除模型对象book.delete()return Response(status=status.HTTP_204_NO_CONTENT)pass

urls.py文件

  # GenericAPIView视图path('booksg/', views.BookGenericAPIView.as_view()),  # 查询所有的图书数据, 类视图;注意:as_view()re_path(r'^booksg/(?P<pk>\d+)/$', views.BookDataGenericAPIView.as_view()),  # 查询详情数据, 类视图;注意:as_view() 必
]

 

2.2五个扩展类

  1. ListModelMixin :列表视图

源码:

views.py

from rest_framework.mixins import ListModelMixin
from rest_framework.generics import  GenericAPIView  #指定过滤化器queryset
class BookListModelMixin(ListModelMixin,GenericAPIView):'''列表视图'''#指定查询集 -数据来源queryset=BookInfo.objects.all()#指定序列化器serializer_class = BookInfoSerializerdef get(self,request):return self.list(request)

urls.py

# ListModelMixin
path('books_lmm/',views.BookListModelMixin.as_view())

2.CreateModelMixin:创建资源的视图

源码:

views.py

from rest_framework.mixins import CreateModelMixin
class BookCreateModelMixinView(CreateModelMixin,ListModelMixin,GenericAPIView):'''创建视图'''#指定查询集 -数据来源queryset=BookInfo.objects.all()#指定序列化器serializer_class = BookInfoSerializer#查询def get(self,request):return self.list(request)#添加def post(self,request):return self.create(request)urls.py
#CreateModelMixin
path('books_cmm/',views.BookCreateModelMixinView.as_view()),

发生异常;

RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/books_cmm/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.

解决:

访问时不应该访问ip/books,

而应该访问ip/books/ 少了一个斜杠

3. RetrieveModelMixin 详情视图

源码:

views.py

from rest_framework.mixins import RetrieveModelMixin
class BookRetrieveModelMixinView(RetrieveModelMixin,GenericAPIView):'''详情视图'''#指定查询集 -数据来源queryset=BookInfo.objects.all()#指定序列化器serializer_class = BookInfoSerializer#查询def get(self,request,pk):return self.retrieve(request)urls.py
# RetrieveModelMixin
re_path(r'^books_xmm/(?P<pk>\d+)/$', views.BookRetrieveModelMixinView.as_view()),   # 查询详情数据, 类视图;注意:as_view() 必

4 UpdateModelMixin: 更新视图

源码:

views.py

from rest_framework.mixins import UpdateModelMixin
class BookUpdateModelMixinView(UpdateModelMixin,RetrieveModelMixin, GenericAPIView):'''更新视图'''# 指定查询集 -数据来源queryset = BookInfo.objects.all()# 指定序列化器serializer_class = BookInfoSerializer# 查询一个def get(self, request,pk):return self.retrieve(request,pk)# 更新def put(self, request,pk):return self.update(request,pk)urls.py
#UpdateModelMixin
re_path(r'^books_umm/(?P<pk>\d+)/$',views.BookUpdateModelMixinView.as_view()),

5 DestroyModelMixin:删除视图

源码:

views.py

from rest_framework.mixins import DestroyModelMixin
class BookDestroyModelMixinView(DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin, GenericAPIView):'''删除视图'''# 指定查询集 -数据来源queryset = BookInfo.objects.all()# 指定序列化器serializer_class = BookInfoSerializer# 查询一个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)Urls.py
# DestroyModelMixin
re_path(r'^books_umm/(?P<pk>\d+)/$',views.BookDestroyModelMixinView.as_view()),

2.3 子类视图

2.4视图集ViewSet

使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

- GET: list() 提供一组数据

- GET: retrieve() 提供单个数据

- POST :create() 创建数据

- PUT :update() 更新数据

- PATCH: partail_update, 更新部分数据

- DELETE:destory() 删除数据

ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上

from rest_framework.viewsets import ViewSet
class BookViewSet(ViewSet):'''视图集'''def list(self,request):'''展示列表数据'''#获取数据all=BookInfo.objects.all()#序列化ser=BookInfoSerializer(all,many=True)#返回数据return Response(ser.data)def retrieve(self,request,pk):'''获取单个数据'''try:book=BookInfo.objects.get(id=pk)except BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)ser=BookInfoSerializer(book)return Response(ser.data)#视图集 ViewSet
#as_view中传入字典参数: 第一个参数:get,post,put,delete等等; 第二个参数:关联的方法名
#as_view中不能定义相同的请求
path('booksv/', views.BookViewSet.as_view({"get": "list"})),
re_path(r'^booksv/(?P<pk>\d+)/$',views.BookViewSet.as_view({"get":"retrieve"})),

2.4.1 ModelViewSet

继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

##########################视图集################
from rest_framework.viewsets import ViewSet
class BookViewSet(ViewSet):'''视图集'''def list(self,request):'''展示列表数据'''#获取数据all=BookInfo.objects.all()#序列化ser=BookInfoSerializer(all,many=True)#返回数据return Response(ser.data)def retrieve(self,request,pk):'''获取单个数据'''try:book=BookInfo.objects.get(id=pk)except BookInfo.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)ser=BookInfoSerializer(book)return Response(ser.data)#视图集 ViewSet
#as_view中传入字典参数: 第一个参数:get,post,put,delete等等; 第二个参数:关联的方法名
#as_view中不能定义相同的请求
path('booksv/', views.BookViewSet.as_view({"get": "list"})),
re_path(r'^booksv/(?P<pk>\d+)/$',views.BookViewSet.as_view({"get":"retrieve"})),

2.4.2视图集中定义附加action动作

在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。

添加自定义动作需要使用`rest_framework.decorators.action`装饰器。

以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。

action装饰器可以接收两个参数:

  1. methods: 该action支持的请求方式,列表传递
  2. detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)

True 表示使用通过URL获取的主键对应的数据对象

False 表示不使用URL获取主键

##########################ModelViewSet################
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
class BookViewSetAction(ModelViewSet):queryset = BookInfo.objects.all()serializer_class = BookInfoSerializer@action(methods=['get'],detail=False)def later(self,request):'''最新的图书信息'''# 获取最后一本书book =BookInfo.objects.latest('id')serializer=self.get_serializer(book)return Response(serializer.data)# detail为True,表示要处理具体与pk主键对应的BookInfo对象# books/pk/read/@action(methods=['put'],detail=True)def readCount(self,request,pk):"""修改图书的阅读量数据"""book =self.get_object()book.read_count=request.data.get('read_count')book.save()serializer=self.get_serializer(book)return Response(serializer.data)#ModelViewSet 注意:遵循ViewSet的规则,必须传字典参数哦!!否则发生错误!!
# ypeError: The `actions` argument must be provided when calling `.as_view()` on a ViewSet. For example `.as_view({'get': 'list'})`
#视图集中包含附加action的
path('books_m/', views.BookViewSetAction.as_view({'get': 'later'})),
re_path(r'^booksm/(?P<pk>\d+)/read/$', views.BookViewSetAction.as_view({'put':'readCount'})),

 http://127.0.0.1:8000/booksm/13/read/

2.5. DefaultRouter与SimpleRouter的区别

DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。`DefaultRouter继承自SimpleRouter`

而使用SimpleRouter则会报错

Django DRF ViewSet(十)相关推荐

  1. Django学习之十: staticfile 静态文件

    目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述 静态文 ...

  2. Django DRF 两种接口安全机制及其配置

    Django DRF 两种接口安全机制及其配置 接口安全机制,用于设置和管理用户调用接口时的权限问题.此处介绍最常用的两种接口安全机制及其配置. 1 使用之前 先生成接口文档 便于测试 1.1 安装依 ...

  3. 快速上手Django(六) -Django之Django drf 序列化器Serializer类

    文章目录 快速上手Django(六) -Django之Django drf 序列化器Serializer类 1. 背景 2. 使用思路 3. 代码demo 4. [重要]序列化类 ModelSeria ...

  4. Django 基础(13)-Django drf 序列化器类to_representation和to_internal_value(处理返回的日期格式)、序列化类 ModelSerializer

    文章目录 一.Django drf 序列化 1. 背景 2. 使用思路 3. 代码demo 4. [重要]序列化类 ModelSerializer 5. DRF序列化器to_representatio ...

  5. Django 基础(12)-Django drf 分页查询(批量查询)、自定义分页器

    文章目录 Django drf 分页查询(批量查询) PageNumberPagination:普通分页 Django 自定义分页器 自定义批量查询的返回结构 LimitOffsetPaginatio ...

  6. Django笔记三十八之发送邮件

    这一篇笔记介绍如何在 Django 中发送邮件. 在 Python 中,提供了 smtplib 的邮件模块,而 Django 在这个基础上对其进行了封装,我们可以通过 django.core.mail ...

  7. Django DRF API

    Django 基本使用 前后端分离开发模式 1.1 前后端分离前 1.2 前后端分离前存在的一些问题 • PC.APP.Pad等多端流行 • 前后端开发职责不清晰:各司其职,最大程度减少开发难度,方便 ...

  8. Django框架(十九)—— drf:序列化组件(serializer)

    序列化组件 # 模型层 from django.db import modelsclass Book(models.Model): nid = models.AutoField(primary_key ...

  9. Django REST framework(十)路由集routers的使用

    Django REST framework(九)-视图集ViewSet.GenericViewSet.ModelViewSet.ReadOnlyModelViewSet_simpleyako的博客-C ...

最新文章

  1. 定义分销渠道(distribution channel)
  2. 无锁并发的CAS为何如此优秀?
  3. CSS框架+响应式设计
  4. GitHub 标星 5.7w,如何用 Python 实现所有算法?
  5. mui多层tab切换上拉加载的实现
  6. atitit.LimeSurvey 安装 attilax 总结
  7. java入门第二天如何使用Elipse
  8. 计算机网络强制100M,网络连通性故障分析与排除二例
  9. 应用时间序列分析案例操作--基于SAS软件,以北京市1980-2009年降水量为对象
  10. JAVA项目中枚举和字典表,枚举与字典表的选择
  11. docker应用篇(6):安装Uptime Kuma监控
  12. C语言之出圈游戏(详解)
  13. 开场白——第一篇博客
  14. from用法 prepare_MySQL之prepare用法
  15. 10行命令60秒快速定位性能瓶颈
  16. 刷新率属于计算机的显示性能指标吗,显示器性能指标(菜鸟必看)
  17. 哒哒哒~~今天说 事务的隔离级别和传播特性
  18. 【xla】六、【构图阶段】xlaRunOp
  19. 垃圾分类对生活的有什么好处
  20. wireshark过滤器

热门文章

  1. 网页三剑客,html/css/javascript
  2. 计算机柜里 do dl代表什么,dl是什么意思(你知道AI、ML和DL分别代表什么吗?)...
  3. gmt转换北京时间 java_java GMT 日期转换 | 学步园
  4. 图像处理----美白
  5. 类脑计算:让人工智能走得更远
  6. python网络爬虫--项目实战--scrapy爬取人人车(5)
  7. 达特茅斯计算机专业师资力量如何,达特茅斯学院(Dartmouth College)计算机科学Computer Science专业排名第126-150位(2021年THE世界大学商科排名)...
  8. operator=函数.
  9. 纯CSS实现beautiful的3D动画
  10. python3安装pip