drf中View和router的详解
Rest Framework 视图和路由
因为涉及到视图层面了,而且下面的例子会反复用到request.data,所以我决定带大家稍微看下源码,感兴趣的可以自己深入了解
无论是View还是APIView最开始都是调用as_view()
大致过了下APIView给我们封装的数据
总结一下
- 旧的request封装到新request属性_request里
- 继承APIView,重新封装的request.query_params相当于旧的request.GET
- request.data相当于旧的request.POST和request.FILES,且支持json数据类型
第一版封装
app/views
class BookView(APIView):
def get(self, request):
query_set = Book.objects.all()
book_ser = BookSerializer(query_set, many=True)
return Response(book_ser.data)
def post(self, request):
query_set = request.data
book_ser = BookSerializer(data=query_set)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.validated_data)
else:
return Response(book_ser.errors)
class BookEditView(APIView):
def get(self, request, pk):
query_set = Book.objects.filter(pk=pk).first()
book_ser = BookSerializer(query_set)
return Response(book_ser.data)
def patch(self, request, pk):
query_set = Book.objects.filter(pk=pk).first()
book_ser = BookSerializer(query_set, data=request.data, partial=True)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.validated_data)
else:
return Response(book_ser.errors)
def delete(self, request, pk):
query_set = Book.objects.filter(pk=pk).first()
if query_set:
query_set.delete()
return Response("")
else:
return Response("删除的书籍不存在")
使用Mixin封装方法
class GenericAPIView(APIView):
queryset = None
serializer_class = None
def get_queryset(self):
return self.queryset.all()
def get_serializer(self,*args,**kwargs):
return self.serializer_class(*args,**kwargs)
class ListModelMixin:
def list(self,request,*args,**kwargs):
queryset = self.get_queryset()
book_sel = self.get_serializer(queryset,many=True)
return Response(book_sel.data)
class CreateModelMixin:
def create(self,request,*args,**kwargs):
book_sel = self.serializer_class(data=request.data)
if book_sel.is_valid():
book_sel.save()
return Response(book_sel.data)
else:
return Response(book_sel.errors)
class UpdateModelMixin:
def update(self,request,pk,*args,**kwargs):
book_obj = self.get_queryset().filter(pk=pk).first()
book_sel = self.serializer_class(book_obj,data=request.data,partial=True)
if book_sel.is_valid():
book_sel.save()
return Response(book_sel.data)
else:
return Response(book_sel.errors)
class RetrieveModelMixin:
def retrieve(self,request,pk,*args,**kwargs):
book_obj = self.get_queryset().filter(pk=pk).first()
book_sel = self.serializer_class(book_obj)
return Response(book_sel.data)
class DestroyModelMixin:
def destroy(self, request, pk, *args, **kwargs):
queryset = self.get_queryset()
try:
queryset.get(pk=pk).delete()
return Response("")
except Exception as e:
return Response("信息有误")
# Create your views here.
class BookEditView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = models.Book.objects
serializer_class = BookSerializers
def get(self,request,pk,*args,**kwargs):
return self.retrieve(request,pk,*args,**kwargs)
def patch(self,request,pk,*args,**kwargs):
return self.update(request,pk,*args,**kwargs)
def delete(self,request,pk,*args,**kwargs):
return self.destroy(request,pk,*args,**kwargs)
class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = models.Book.objects
serializer_class = BookSerializers
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs)
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs)
# 技术点:因为drf中的GenericAPIView提供了queryset和serializer_class,如果要继承GenericAPIView,
# 则必须重写这两个字段,且GenericAPIView提供get_queryset和get_serializer两个方法
# Mixin类不用继承其他API,只是单独提供方法接口,必须跟其他API类混合继承
感觉经过这么一封装,每个类中的方法看起来清爽多了,我们还可以继续封装
第二版封装
# 上面我们写的继承类太长了~~我们再改改
class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
pass
class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
pass
class BookEditView(RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects
serializer_class = BookSerializers
def get(self,request,pk,*args,**kwargs):
return self.retrieve(request,pk,*args,**kwargs)
def patch(self,request,pk,*args,**kwargs):
return self.update(request,pk,*args,**kwargs)
def delete(self,request,pk,*args,**kwargs):
return self.destroy(request,pk,*args,**kwargs)
class BookView(ListCreateAPIView):
queryset = models.Book.objects
serializer_class = BookSerializers
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs)
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs)
感觉只是把类中的继承稍微简化了下,并不是特别的优雅,来康康第三版
第三版封装
我们知道,一般的View执行as_view()不能传入参数,接下来要介绍的ViewSetMixin,重写了as_view(actions),可以传入我们需要的参数
urlpatterns = [
url(r'^book$', BookView.as_view({"get": "list", "post": "create"})),
url(r'^retrieve/(?P<pk>\d+)$', BookEditView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})), //这里要注意的是,使用这种传参的view,传入的动态id要命名为pk
]
urls.py
from rest_framework.viewsets import ViewSetMixin
# class BookView(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
# queryset = Book.objects.all()
# serializer_class = BookSerializer
# 如果我们再定义一个类
class ModelViewSet(ViewSetMixin, ListCreateAPIView):
pass
class OwnViewSet(ViewSetMixin,RetrieveUpdateDestroyAPIView)
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookEditView(OwnViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
我们现在的视图就只要写两行就可以了,其实我们写的所有的视图~框架都帮我们封装好了,刚刚上面用的例子都是手动封装
奉献一张图来看下我们的继承顺序~~~
drf的路由
我们上面的路由传参写的特别多~~框架也帮我们封装好了~
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r"book", BookView)
urlpatterns = [
]
urlpatterns += router.urls
通过框架的路由可以看出,手写的代码几乎没有了,这里提出一点建议,如果自己的业务逻辑不是跟增删改查特别耦合
不建议用drf提供的路由组件,因为这样会暴露很多的接口,不太安全,总之,一般我们很少用到这个组件,还是尽量自己手写
总结
类的继承链越高,所拥有的功能也就越少,可定制化的程度就越高,尽管上面我们用底层的类,特别轻松的实现了功能,
但需要自定制时,还是继承APIView实现自己的业务逻辑,总之一切按照业务逻辑来走
参考链接
https://www.cnblogs.com/GGGG-XXXX/articles/9675911.html
drf中View和router的详解的更多相关文章
- 【Unity编程】Unity中关于四元数的API详解
本文为博主原创文章,欢迎转载,请保留出处:http://blog.csdn.net/andrewfan Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计 ...
- [ 转载 ] Java开发中的23种设计模式详解(转)
Java开发中的23种设计模式详解(转) 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...
- Linux中/proc目录下文件详解
转载于:http://blog.chinaunix.net/uid-10449864-id-2956854.html Linux中/proc目录下文件详解(一)/proc文件系统下的多种文件提供的系统 ...
- JQuery在循环中绑定事件的问题详解
JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...
- C#中的Linq to Xml详解
这篇文章主要介绍了C#中的Linq to Xml详解,本文给出转换步骤以及大量实例,讲解了生成xml.查询并修改xml.监听xml事件.处理xml流等内容,需要的朋友可以参考下 一.生成Xml 为了能 ...
- 批处理中的echo命令图文详解
批处理中的echo命令图文详解 1. Echo 显示当前ECHO的状态:ECHO ON 或者ECHO OFF 2. ECHO ON 将ECHO状态设置为ON,将显示命令行,也就是前面的C:\>类 ...
- C#中的预处理器指令详解
这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...
- SVN中tag branch trunk用法详解
SVN中tag branch trunk用法详解 2010-05-24 18:32 佚名 字号:T | T 本文向大家简单介绍一下SVN中tag branch trunk用法,SVN中tag bran ...
- JavaScript中的鼠标滚轮事件详解
JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...
随机推荐
- HDU Typewriter 6583 dp SAM 卡常
LINK:Typewriter 好久没写SAM了 什么都给忘了. 写了大概2h.感觉被卡常还看了题解. 考虑dp 然后容易想到维护前面的一个j决策 尽可能小. 然后每次考虑向后加一个字符 不过不行就跳 ...
- 5.10 省选模拟赛 拍卖 博弈 dp
LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...
- 大话Android中的Handler机制
在Android的线程间通信中,Handler独当一面,无论是framework层还是app层中都出现的相当频繁,有必要好好的拿出来深挖一下它的实现原理.而要说Handler的通信机制,除了Handl ...
- x86架构:保护模式下加载并运行用户程序
本章的代码分3个模块: MBR 引导:加载内核core程序 core:包含内核代码段(从磁盘加载用户程序并重定位).内核数据段(存放api名称.临时缓冲.字符串等).API段(供用户程序调用) 用户程 ...
- Jvm相关文章
深入理解JVM-内存模型(jmm)和GC https://www.jianshu.com/p/76959115d486
- RNN神经网络模型原理
1. 前言 循环神经网络(recurrent neural network)源自于1982年由Saratha Sathasivam 提出的霍普菲尔德网络. 传统的机器学习算法非常依赖于人工提取的特征, ...
- C语言学习笔记之输出缓冲
在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...
- 《Java核心技术(卷1)》笔记:第12章 并发
线程 (P 552)多进程和多线程的本质区别:每一个进程都拥有自己的一整套变量,而线程共享数据 (P 555)线程具有6种状态: New(新建):使用new操作符创建线程时 Runnable(可运行) ...
- Django中信号signal针对model的使用
Django中实现对数据库操作的记录除了使用[开源插件]还可以使用信号signal独立实现 信号机制-观察者模式-发布与订阅:signal - 配置 # 文件路径:Django/myapps/__in ...
- 检查型异常和非检查型异常——Java
文章目录 检查型异常和非检查型异常--Java 检查型异常 非检查型异常 结语 检查型异常和非检查型异常--Java Java语言规范将派生于Error类或RuntimeExceprion类的所有异常 ...