Django rest framework (视图类详解)
官网: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、可以很容易地,组成可重复使用的行为。
Django rest framework (视图类详解)的更多相关文章
- Cocoa编程中视图控制器与视图类详解
iPhone编程规则是:一个窗口,多个视图.UIView是iPhone屏幕上很多控件的基础类.每个iPhone用户界面都是由显示在UIWindow(这其实也是个特殊的UIView)内的众多UIView ...
- Django Rest Framework(2)-----序列化详解(serializers)
REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSe ...
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
- Django之form表单详解
构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板: <form action="/your-name/" method=" ...
- QAction类详解:
先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...
- ThinkPHP视图查询详解
ThinkPHP视图查询详解 参考http://www.jb51.net/article/51674.htm 这篇文章主要介绍了ThinkPHP视图查询,需要的朋友可以参考下 ThinkP ...
- Django Rest Framework 视图和路由
Django Rest Framework 视图和路由 DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们 ...
- python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)
昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...
- Django REST framework - 视图
目录 Django REST framework 视图GenericAPIView GenericAPIView 例子 属性 混入 具体视图类 自定义基类 Django REST framework ...
随机推荐
- Eclipse导入Maven项目解决Build Path不能配置问题
Eclipse Mars Release (4.5.0)导入Maven项目时,发现项目Build Path不能配置,如下图所示: 解决办法: 1修改Project Facets 项目右键---> ...
- leetcood学习笔记-404-左叶子之和
题目描述: 方法一:递归 class Solution: def sumOfLeftLeaves(self, root: TreeNode) -> int: if not root: retur ...
- EasyUI - 简介
1. EasyUI : 简单的界面设计框架, 基于jQuery的UI插件, 主要用来设计网站的后台管理系统 2. EasyUI使用 : 将EasyUI提供的js文件和主题(themes)样式存放到项目 ...
- php数组长度怎么获取
我们可以将元素添加到数组或从数组中删除元素,那么如果我们想要知道数组中存在的元素的总长度或总数,我们就可以使用count() 或sizeof函数. 下面我们就通过简单的示例,给大家介绍php获取数组长 ...
- NTT数论变换
数论变换NTT 前置知识 FFT:NTT的思想和FFT一样(FFT介绍) 概述 数论变换,即NTT(Number Theory Transformation?),是基于数论域的FFT,一般我们默认FF ...
- QString与string的相互转换【转载】
文章转载自https://blog.csdn.net/qq_33485434/article/details/80680506 1.QString转换String string s = qstr.to ...
- P1566 加等式
P1566 加等式 题目描述 对于一个整数集合,我们定义“加等式”如下:集合中的某一个元素可以表示成集合内其他元素之和.如集合{1,2,3}中就有一个加等式:3=1+2,而且3=1+2 和3=2+1是 ...
- C++之引用与符号“&”
一.&的意思: 1.取地址符,这时候它用于数据的前面,比如int a=&b; 2.C++里还使用&作为引用符,如果你确认程序是标准的C而非C++的话,那么可以排除是引用了.引用 ...
- 剑指offer——11矩阵覆盖
题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 题解: 使用递归或者动态规划,明显,递归没有动态规划优 ...
- 20140404 OpencvGPU模块 参考文献交叉引用:引用->题注 加入3.1,3.2,3.2编号
1.参考文献交叉引用:引用->题注 2.加入3.1,3.2,3.2编号:开始->段落 3.OpencvGPU模块,编译opencv.sln时记得在库目录中添加D:\opencv\build ...