官网:https://www.django-rest-framework.org/api-guide/viewsets/

在django rest framework 视图中一共有N个类

第一类:APIview

class IndexView(APIView):

    def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
queryset = models.UserInfo.objects.get(pk=pk)
ser = UserInfoSerializer(instance=queryset,many=False)
else:
queryset = models.UserInfo.objects.all()
ser = UserInfoSerializer(instance=queryset,many=True)
return Response(ser.data)
#

这种直接继承了APIView,是最原始的。请求方式就是那五种,get,post,put,patch,delete

第二类 GenericAPIView

class IndexView(GenericAPIView):
queryset = models.UserInfo.objects.all()
serializer_class = UserInfoSerializer
lookup_field = 'pk' def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
users = self.filter_queryset(queryset=models.UserInfo.objects.get(pk=pk))
ser = self.get_serializer(instance=users)
else:
users = self.get_queryset()
ser = self.get_serializer(instance=users,many=True)
return Response(ser.data)

在GenericAPIView中要重写一些字段和方法,不常用。

第三类 GenericViewSet

class IndexView(GenericViewSet):
serializer_class = UserInfoSerializer
queryset = models.UserInfo.objects.all()
def create(self,request,*args,**kwargs):
pass def list(self,request,*args,**kwargs): # 获取列表数据
users = models.UserInfo.objects.all()
ser = UserInfoSerializer(instance=users,many=True)
return Response(ser.data) def retrieve(self,request,*args,**kwargs): # 获取单条数据
pk = kwargs.get('pk')
users = models.UserInfo.objects.get(pk=pk)
ser = UserInfoSerializer(instance=users,many=False)
return Response(ser.data) def destroy(self,request,*args,**kwargs):
pass def update(self,request,*args,**kwargs):
pass def partial_update(self,request,*args,**kwargs):
pass

这个类继承了ViewSetMixin, generics.GenericAPIView,其中在ViewSetMixin中会重写as_view()方法,因此可以将URL中的请求方式与视图函数绑定到一起,在urls.py中以键值对的方式存在:
urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^hehe/', views.hehe),
url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})),
url(r'^index/(?P<pk>\d+)/$', views.IndexView.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'})),
]

ViewSetMixin源码部分:

class ViewSetMixin(object):
"""
This is the magic. Overrides `.as_view()` so that it takes an `actions` keyword that performs
the binding of HTTP methods to actions on the Resource. For example, to create a concrete view binding the 'GET' and 'POST' methods
to the 'list' and 'create' actions... view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
""" @classonlymethod
def as_view(cls, actions=None, **initkwargs):
"""
Because of the way class based views create a closure around the
instantiated view, we need to totally reimplement `.as_view`,
and slightly modify the view function that is created and returned.
"""
# The suffix initkwarg is reserved for displaying the viewset type.
# eg. 'List' or 'Instance'.
cls.suffix = None # Setting a basename allows a view to reverse its action urls. This
# value is provided by the router through the initkwargs.
cls.basename = None # actions must not be empty
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`") # sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r" % (
cls.__name__, key)) def view(request, *args, **kwargs):
self = cls(**initkwargs)
# We also store the mapping of request methods to actions,
# so that we can later set the action attribute.
# eg. `self.action = 'list'` on an incoming GET request.
self.action_map = actions # Bind methods to actions
# This is the bit that's different to a standard view
for method, action in actions.items():
handler = getattr(self, action) # 通过反射获取请求方式
setattr(self, method, handler) # 绑定到视图函数中的方法 if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get self.request = request
self.args = args
self.kwargs = kwargs # And continue as usual
return self.dispatch(request, *args, **kwargs) # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=()) # We need to set these on the view function, so that breadcrumb
# generation can pick out these bits of information from a
# resolved URL.
view.cls = cls
view.initkwargs = initkwargs
view.suffix = initkwargs.get('suffix', None)
view.actions = actions
return csrf_exempt(view) def initialize_request(self, request, *args, **kwargs):
"""
Set the `.action` attribute on the view,
depending on the request method.
"""
request = super(ViewSetMixin, self).initialize_request(request, *args, **kwargs)
method = request.method.lower()
if method == 'options':
# This is a special case as we always provide handling for the
# options method in the base `View` class.
# Unlike the other explicitly defined actions, 'metadata' is implicit.
self.action = 'metadata'
else:
self.action = self.action_map.get(method)
return request def reverse_action(self, url_name, *args, **kwargs):
"""
Reverse the action for the given `url_name`.
"""
url_name = '%s-%s' % (self.basename, url_name)
kwargs.setdefault('request', self.request) return reverse(url_name, *args, **kwargs)

第四类 ModelViewSet 继承了这个类,ModelViewSet继承了四个混入类和一个泛类,

将会获得增删改查的所有方法。

class IndexView(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserInfoSerializer

class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass

使用类视图的好处:
1、我们将各个HTTP请求方法之间,做了更好的分离。
2、可以很容易地,组成可重复使用的行为。

最新文章

  1. CODEVS 1817 灾后重建 Label:Floyd || 最短瓶颈路
  2. Javascript AMD学习
  3. ASP.NET WebAPI 03 返回结果
  4. 【HTML5】Canvas和SVG的区别
  5. web.xml总结整理
  6. 关于JDBC链接数据库的代码实现
  7. java中json转xml
  8. 新的一年新的气象 云计算与SOA
  9. ffmpeg.c函数结构简单分析(画图)
  10. 《贝贝GO》服务条款
  11. Codeforces 449C Jzzhu and Apples 贪心 (看题解)
  12. android-基础编程-Dialog
  13. c语言版本的coroutine
  14. 数据提交方式:post和get
  15. 谁说他们版本不兼容——hadoop1.2.1+hbase0.94.11+nutch2.2.1+el
  16. 【题解】洛谷P3953 [NOIP2017TG] 逛公园(记忆化搜索+SPFA)
  17. 160808、Java的不同版本:J2SE、J2EE、J2ME的区别
  18. nohup 无发后台运行
  19. How Tomcat Works(十九)
  20. 查看java版本

热门文章

  1. Centos6.5 安装 LAMP
  2. java web应用用户上传图片的存储地址
  3. JAVA去除抖音视频的水印源码!!!
  4. [转]在WPF中自定义控件 UserControl
  5. IIS查找报错信息
  6. linux命令系列-tar(打包压缩)
  7. wordpress翻译插件gtranslate
  8. Java-Class-C:org.springframework.http.converter.StringHttpMessageConverter
  9. 信息安全-技术-Web:cookie
  10. Instrumentation 实践详解