一、视图类

#bookview是一个视图类,继承自ModelViewSet
class BookView(ModelViewSet):
throttle_classes = [VisitThrottle2]
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer

ModelViewSet

ModelViewSet:
class ModelViewSet(mixins.CreateModelMixin, # 实现了post添加逻辑
mixins.RetrieveModelMixin, # 实现了获取具体某一本书的逻辑
mixins.UpdateModelMixin, # 实现了put编辑的逻辑
mixins.DestroyModelMixin, # 实现了删除一本书的逻辑
mixins.ListModelMixin, # 实现了获取所有书的逻辑
GenericViewSet): # 提供了APIView和dispatch的功能
....
由于ModelViewSet继承了多个混合类和通用视图类,所以ModelViewSet提供了.list(),.retrieve(), .create(),.update(),.partial_update(),和.destroy()
因为ModelViewSet继承了GenericViewSet,所以BookView需要提供queryset和serializer_class属性

二、执行流程

1. url:

url(r'books/$',views.BookView.as_view({'get':'list','post':'create'})),
url(r'books/(?P<pk>\d+)/$',views.BookDetailView.as_view({'get': 'retrieve',
'put':'update',
'delete':'destroy'})),

当django启动的时候,会执行view.BookView.as_view()方法:由于as_view()是从ViewSetMixin中继承而来的,所以url会变为:

url(r'books/$',ViewSetMixin.view),
url(r'books/(?P<pk>\d+)/$',ViewSetMixin.view),

2.当用户访问books/的时候,会调用执行ViewSetMixin.view并传入request。

class ViewSetMixin(object):
"""
他是一个魔法方法
重写`.as_view()‘,以便它接受一个’actions‘关键字,
该关键字执行HTTP方法到资源上的操作的绑定。
例如,要创建一个将“GET”和“POST”方法绑定到“List”和“Create”操作的具体视图.
view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
"""
def view(request, *args, **kwargs):
self = cls(**initkwargs)
self.action_map = actions # {'get':'list','post':'create'}
# {'get': 'retrieve','put':'update','delete':'destroy'} for method, action in actions.items():
# self:ModelViewSet继承的每一个类 action是list create等方法。
# handler是每一个具体的函数名
handler = getattr(self, action)
#为属性赋值, self.get = list, self.get = retrieve
# 当get请求的时候,真正会执行的是list/retrieve方法
setattr(self, method, handler) # 进行分发,由于以上几个类都没有实现该方法,所以dispatch()执行的是APIView的dispatch()
return self.dispatch(request, *args, **kwargs)

3.ViewSetMixin的view主要是把mixins中的list()、create()、retrieve()、等绑定给BookView的get()、post()等。

4.dispatch()

def dispatch(self, request, *args, **kwargs):

            try:
self.initial(request, *args, **kwargs) # get、put、post等请求方法,去list、create、update等,去执行
if request.method.lower() in self.http_method_names: # 这里的self是ViewSetMixin。
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

当客户端请求方式是get的时候,执行BookView的get()方法,实际上是执行的list().因为在ViewSetMixin.view()中,获取minx下的list、create等函数地址,通过settattr()的方式绑给了BookView实例对象

三、总结:

django启动******

        url(r'books/$',views.BookView.as_view({'get':'list','post':'create'})),   1
url(r'books/$',ViewSetMixin.view)), 2 一旦用户访问****** books get请求 def view(request, *args, **kwargs):
self = cls(**initkwargs)
{'get':'list','post':'create'} for method, action in actions.items(): handler = getattr(self, action)
#给BookView设置一个属性 BookView.get = ListModelMixin.list
setattr(self, method, handler) return self.dispatch(request, *args, **kwargs) url(r'books/$',APIView.dispatch)), 3 if get in self.http_method_names: # 这里的self是ViewSetMixin。
handler = getattr(self, 'get'), --> BookView.get ---> 实际上执行的是 ListModelMixin.list
self.http_method_not_allowed) handler返回什么,dispatch返回什么,view返回什么,用户看到什么

Django Rest Framework----ModelViewSet视图 ModelViewSet源码分析的更多相关文章

  1. Django rest framework 的认证流程(源码分析)

    一.基本流程举例: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', views.HostView.as_view() ...

  2. django Rest Framework----GenericAPIView 通用视图 GenericAPIView源码分析

    一.GenericAPIView GenericAPIView扩展了APIView,为标准列表和详细视图添加了常见的行为. 提供的每个具体通用视图都是一个GenericAPIView或多个mixin类 ...

  3. Django rest framework 限制访问频率(源码分析)

    基于 http://www.cnblogs.com/ctztake/p/8419059.html 当用发出请求时 首先执行dispatch函数,当执行当第二部时: #2.处理版本信息 处理认证信息 处 ...

  4. Django_Restframwork_APIVIEW视图_源码分析

    Django _VIEW视图_源码分析

  5. django Rest Framework----APIView 执行流程 APIView 源码分析

    在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...

  6. Django之admin的使用及源码分析

    一.admin组件使用 Django本身提供了基于 web 的管理工具.其管理工具是django.contrib的一部分,可在settings.py中的 INSTALLED_APPS 看到: INST ...

  7. Django(63)drf权限源码分析与自定义权限

    前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...

  8. Django(64)频率认证源码分析与自定义频率认证

    前言 有时候我们发送手机验证码,会发现1分钟只能发送1次,这是做了频率限制,限制的时间次数,都由开发者自己决定 频率认证源码分析 def check_throttles(self, request): ...

  9. Django day24 cbv和APIView的源码分析 和 resful的规范

    一:cbv的源码分析 1.CBV和FBV的区别: - Class Base View   CBV(基于类的视图) - Function Base View   FBV(基于函数的视图) 2.as_vi ...

  10. Django框架(十七)-- CBV源码分析、restful规范、restframework框架

    一.CBV源码分析 1.url层的使用CBV from app01 import views url(r'book/',views.Book.as_view) 2.as_view方法 as_view是 ...

随机推荐

  1. Leetcode模拟题篇

    43. Multiply Strings 高精度非负整数的乘法. string multiply(string num1, string num2) { '); ; <= i; --i) { ; ...

  2. SpringBoot之使用jpa/hibernate

    Springboot版本是2.1.3.RELEASE 1.依赖 List-1.1 <dependency> <groupId>org.springframework.boot& ...

  3. ajax请求提交到controller后总是不成功

    最近在做实习时,点击查询时在js中发送ajax请求到controller后台,但是无论怎么样都不成功,请求地址是正确的,因为在后台用system.out.println输出有值,并且也确实return ...

  4. 【BZOJ1048】分割矩阵(记忆化搜索,动态规划)

    [BZOJ1048]分割矩阵(记忆化搜索,动态规划) 题面 BZOJ 洛谷 题解 一个很简单的\(dp\),写成记忆化搜索的形式的挺不错的. #include<iostream> #inc ...

  5. 模板:快速傅里叶变换(FFT)

    参考:http://blog.csdn.net/f_zyj/article/details/76037583 如果公式炸了请去我的csdn博客:http://blog.csdn.net/luyouqi ...

  6. 【BZOJ1801】【Ahoi2009】chess 中国象棋

    Time Limit: 10 Sec Memory Limit: 64 MB Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方 ...

  7. Linux及安全实践三——程序破解

    Linux及安全实践三--程序破解 一.基本知识 常用指令机器码 指令 作用 机器码 nop 无作用(no operation) 90 call 调用子程序,子程序以ret结尾 e8 ret 返回程序 ...

  8. Mac显示同一程序的所有窗口

    通过F3键可以显示所有程序的所有窗口到桌面,但是如果窗口太多的话显示出来很难看清. 如果只显示某一个程序的所有窗口就不会乱了. 其实在dock上有一个相应的选项,但是没有快捷键. 开启方法: 在终端上 ...

  9. 仿微博的JQuery日历控件

    实现原理主要是处理table,生成tr td,其中最重要的是如何找出每月第一天是星期几,然后就能对应出这个月的余下天数. 日历控件网上一搜一大把,但是我觉得自己写一遍还是有好处的.代码可以查看本页源代 ...

  10. centos systemctl daemon-reload 提示 no such file or directory 的一个原因

    service 的文件名写错了 比如 mongodb.service 写成了 mongodb.srvice 真的是坑,居然没有提示具体的路径,只是提示一个 no such file or direct ...