DRF框架-View视图
View视图使用
推荐官网:https://www.django-rest-framework.org/api-guide/views/
APIView(一级视图)
集成于Django的view类,和view不同地方在于:
传递给处理程序方法的请求将是REST框架的Request实例,而不是Django的HttpRequest实例。
处理程序方法可能返回REST框架的Response,而不是Django的HttpResponse…视图将管理内容协商和在响应上设置正确的呈现器。
任何APIException例外情况将被捕获并调解成适当的反应。
传入的请求将进行身份验证,并在将请求发送给处理程序方法之前,将运行适当的权限和/或节流检查。
点击查看类内容:
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
# 身份认证
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
写一个get和post请求实例:
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from rest_framework import authentication, permissions
from goods.serializers import *
class ListGoodsView(APIView):
# 可以不需要验证
# authentication_classes = (authentication.TokenAuthentication, )
# permission_classes = (permissions.IsAdminUser, )
def get(self, request, format=None):
goods = [good.name for good in GoodsInfo.objects.all()]
# 多条数据要写many=True
data = GoodsInfo.objects.all()
ser = GoodsInfoNewSerializer(data, many=True)
return Response(ser.data)
def post(self, request):
# 反序列化需要data=
ser = GoodsInfoNewSerializer(data=request.data)
# 需要验证
ser.is_valid()
print(ser.validated_data)
ser.save()
return Response(ser.validated_data)
GenericAPIView(二级视图)和mixins
这个是对APIView的再次封装,实现更强和更简洁的功能,通常还会和mixins联合使用:
GenericAPIView的属性
加入queryset属性,可以直接设置这个属性,不必再将实例化的courses,再次传给seriliazer,系统会自动检测到。除此之外,可以重载get_queryset(),这样就不必设置’queryset=*’,这样就变得更加灵活,可以进行完全的自定义。
加入serializer_class属性与实现get_serializer_class()方法。两者的存在一个即可,通过这个,在返回时,不必去指定某个serilizer
lookup_field-模型字段,用于对单个模型实例执行对象查找。默认为’pk’…注意,在使用超链接API时,需要确保双管齐下API视图和如果需要使用自定义值,序列化程序类将设置查找字段
设置过滤器模板:filter_backends
设置分页模板:pagination_class
mixins类
1.ListModelMixin
列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码。
该Mixin的list方法会对数据进行过滤和分页。
2.CreateModelMixin
创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。
3.RetrieveModelMixin
详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象。
如果存在,返回200, 否则返回404。
4.UpdateModelMixin
更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象。
同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
成功返回200,序列化器校验数据失败时,返回400错误。
5.DestroyModelMixin
删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象。
成功返回204,不存在返回404。
混合使用实例:
mixins的子类中会带有对应可以使用的方法,看上文,这时候要写queryset和serializer_class以及对应的请求方式,并返回mixins子类中的方法
from goods.serializers import *
from rest_framework.mixins import *
from rest_framework.generics import *
class GenericsView(GenericAPIView, ListModelMixin):
queryset = GoodsInfo.objects.all()
serializer_class = GoodsInfoNewSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
如果直接使用下文的子类更简单:
意思是自动调用post方法,不需要再自己调用这个方法
from goods.serializers import *
from rest_framework.generics import *
class CreateGoodsView(CreateAPIView):
# queryset = GoodsInfo.objects.all() # 创建的时候可以不用设置数据库内容
serializer_class = GoodsInfoNewSerializer
三级视图(XXAPIView)
使用已有的子类代表GenericAPIView和mixins的混合使用
几个子类视图
1.CreateAPIView
提供 post 方法
继承自: GenericAPIView、CreateModelMixin
2.ListAPIView
提供 get 方法
继承自:GenericAPIView、ListModelMixin
3.RetireveAPIView
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin
4.DestoryAPIView
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin
5.UpdateAPIView
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin
6.RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
7.RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
ViewSet的使用
视图集ViewSet,使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中。使用ViewSet时不需要再views.py里写get->return list这种类型的,只需要在urls.py里写对应逻辑:
views.py内容:自己导包
class MyViewSet(GenericViewSet, ListModelMixin):
queryset = GoodsInfo.objects.filter(id__gt=15)
serializer_class = GoodsInfoNewSerializer
class GoodsInfoView(ModelViewSet):
# 先导包ModelViewSet和数据库Model和serializers下的类
# queryset是一个查询集,存储所有的数据库查询之后的数据,是一个属性不能修改名字
queryset = GoodsInfo.objects.all()
'''serializer_class用来指定再当前的视图立面进行序列化和反序列化时
使用的序列化器(也叫串行器)'''
serializer_class = GoodsInfoNewSerializer
urls.py内容,两种方式,router是自动完成绑定:
from django.conf.urls import url, include
from goods.views import *
from rest_framework.routers import DefaultRouter
# 定义视图处理的路由器
router = DefaultRouter()
# 在路由器中注册视图集
router.register('showgoods', GoodsInfoView, base_name='hello')
router.register('viewset', MyViewSet, base_name='viewset')
urlpatterns = [
url(r'', include(router.urls)),
url(r'^goodslist/$', ListGoodsView.as_view()),
url(r'^show/$', GenericsView.as_view()),
url(r'^(?P<pk>\d+)+(/showgoods/)$', GoodsInfoView.as_view({'get':'retrieve','post':'create','put':'update'})),
]
或者这样写:
viewset = MyViewSet.as_view({
'get': 'list',
})
# 商品列表页
url('viewset/', goods_list,name="viewset"),
1. ViewSet
继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
2.GenericViewSet
继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。
3.ModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
4.ReadOnlyModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
ViewSet添加自定义动作
添加自定义动作需要使用rest_framework.decorators.action装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
methods: 该action支持的请求方式,列表传递
detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
True 表示使用通过URL获取的主键对应的数据对象
False 表示不使用URL获取主键
实例:
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
# detail为False 表示不需要处理具体的BookInfo对象
@action(methods=['get'], detail=False)
def latest(self, request):
"""
返回最新的图书信息
"""
book = BookInfo.objects.latest('id')
serializer = self.get_serializer(book)
return Response(serializer.data)
# detail为True,表示要处理具体与pk主键对应的BookInfo对象
@action(methods=['put'], detail=True)
def read(self, request, pk):
"""
修改图书的阅读量数据
"""
book = self.get_object()
book.bread = request.data.get('read')
book.save()
serializer = self.get_serializer(book)
return Response(serializer.data)
urls.py的跳转逻辑:
urlpatterns = [
url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),
url(r'^books/latest/$', views.BookInfoViewSet.as_view({'get': 'latest'})),
url(r'^books/(?P<pk>\d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
url(r'^books/(?P<pk>\d+)/read/$', views.BookInfoViewSet.as_view({'put': 'read'})),
]
上一篇: 信号的捕捉与模拟实现sleep函数
推荐阅读
-
Laravel框架视图和模型操作方法分析
-
解读ASP.NET 5 & MVC6系列教程(16):自定义View视图文件查找逻辑
-
Laravel框架控制器,视图及模型操作图文详解
-
在Django的视图(View)外使用Session的方法
-
详解Django框架中的视图级缓存
-
在Python的Django框架的视图中使用Session的方法
-
Django框架下在URLconf中指定视图缓存的方法
-
Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
-
Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)
-
laravel框架中视图的基本使用方法分析