前后端分离djangorestframework——视图组件
CBV与FBV
CBV之前说过就是在view.py里写视图类,在序列化时用过,FBV就是常用的视图函数,两者的功能都可以实现功能,但是在restful规范方面的话,CBV更方便,FBV还要用request.method来判断是get,put,post等的,在CBV里要用什么就定义什么方法,根据请求的方法自动进入对应的CBV的方法里,节省了判断请求类型的过程
View与APIView
APIView就是在View上做了二次封装,多了一些功能而已,View是django自带的视图组件
在 前后端分离djangorestframework——序列化与反序列化数据 这篇文章中(所以接下来用到的数据还是这篇文章里用到的数据),利用了DRF的序列化与反序列化,感受了下DRF的特性,但其实视图部分的代码还是有点冗余,假如以后有上百个url,就要给上百个url写对应的视图类,然后对数据的增删改查,都要重写一次,这样功能是可以实现,但是太low了,需要改善下
View的第一次改版
每次在重复书写的是数据库表的操作,序列化类的操作,以及不同的请求方式对应的视图类的方法,所以可以微调一下:
修改数据库表和序列化类,重新定义一个类,代替操作,此后这个GenericView类可以被所有的视图类继承了,简直是一劳永逸的

再重组请求方式对应的方法:

访问页面看有没有问题:

添加一个字段看看:

成功:

可能你访问list时还没看到数据,打开数据库库查看是有的,多刷新几次页面就有了:

好的,把剩下的对单调数据操作的也改了
全部代码:
# coding:utf-8
from django.shortcuts import HttpResponse
from django.views import View
from demo1 import models
from django.core import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from demo1.serializers import BookSerializer
class OldBookView(View):
# def get(self, request):
# book_list = models.Book.objects.values("id", "title", 'pub_time','publisher')
# book_list = list(book_list)
# ret = []
# for field in book_list:
# pub_id = field['publisher']
# publish_obj = models.Publisher.objects.filter(id=pub_id).first()
# field['publisher'] = {
# 'id':pub_id,
# 'title':publish_obj.title
# }
# ret.append(field)
#
# return JsonResponse(ret, safe=False, json_dumps_params={'ensure_ascii': False})
def get(self, request):
book_list = models.Book.objects.all()
ret = serializers.serialize('json', book_list, ensure_ascii=False)
return HttpResponse(ret)
class GenericAPIView(APIView):
query_set = None
serializer_class = None
def get_queryset(self):
return self.query_set
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
# Mixin字段的都是混合类,需要混合继承
class ListModelMixin(object):
def list(self, request):
book_list = self.get_queryset()
ret = self.get_serializer(book_list, many=True)
return Response(ret.data)
class CreateModelMixin(object):
def create(self, request):
serialize = self.get_serializer(data=request.data)
if serialize.is_valid():
# save是存储
serialize.save()
return Response(serialize.data)
else:
return Response(serialize.errors)
class BookView(GenericAPIView, CreateModelMixin, ListModelMixin):
query_set = models.Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
# book_list = self.get_queryset()
# ret = self.get_serializer(book_list, many=True)
# return Response(ret.data)
return self.list(request)
def post(self, request):
# serialize = self.get_serializer(data=request.data)
# if serialize.is_valid():
# serialize.save()
# return Response(serialize.data)
# else:
# return Response(serialize.errors)
return self.create(request)
class RetrieveModelMixin(object):
def list(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
ret = self.get_serializer(book_obj)
return Response(ret.data)
class RetrieveUpdateModelMixin(object):
def update(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
# partial参数表示只对部分数据验证
serialize = self.get_serializer(book_obj, data=request.data, partial=True)
if serialize.is_valid():
serialize.save()
return Response(serialize.data)
else:
return Response(serialize.errors)
class RetrieveDestoryModelMixin(object):
def destory(self, request, id):
book_obj = self.get_queryset().filter(id=id).exists()
if not book_obj:
return Response('不存在id为%s的数据,请重试' % id)
else:
self.get_queryset().filter(id=id).delete()
return Response("删除成功")
class BookEditView(GenericAPIView, RetrieveModelMixin, RetrieveUpdateModelMixin, RetrieveDestoryModelMixin):
query_set = models.Book.objects.all()
serializer_class = BookSerializer
def get(self, request, id):
# book_obj = models.Book.objects.filter(id=id).first()
# ret = BookSerializer(book_obj)
# return Response(ret.data)
return self.list(request, id)
def put(self, request, id):
# book_obj = models.Book.objects.filter(id=id).first()
# # partial参数表示只对部分数据验证
# serialize = BookSerializer(book_obj, data=request.data, partial=True)
#
# if serialize.is_valid():
# # print(serialize.validated_data)
# # save是存储
# serialize.save()
# return Response(serialize.data)
# else:
# return Response(serialize.errors)
return self.update(request, id)
def delete(self, request, id):
# book_obj = models.Book.objects.filter(id=id).exists()
# if not book_obj:
# return Response('不存在id为%s的数据,请重试' % id)
# else:
# models.Book.objects.filter(id=id).delete()
# return Response("删除成功")
return self.destory(request, id)
修改视图CBV-第一版
访问:

修改:

删除:


没有问题
View的第二次改版
有几个视图类继承好多个类,再次微调,再定义两个类只是继承那些类,然后视图类再继承此类,相对刚才没有做任何改动,就多了一个中间父类而已

View的第三次改版
还有个问题,看url,都是对Book表的操作,但是却有两个视图类来处理,不太符合restful规范

修改url,给as_view添加一个字典参数,但是默认as_view是不可以传参的,所以我们需要自己封装一个可以传参的类 
补充,我传的as_view参数中,对单条数据修改的retrieve的get方式由之前的"get":"list"已经改成了'get':'retrieve',对应的自定义RetrieveMixin里的方法也由list改成了retrieve,因为和上面对多条数据的"get":"list" 重复了,为了防止报错,所以修改了
定义类,修改as_view传参:
具体的逻辑代码就不写了,因为DRF自带了
直接用DRF定义的View——ModelViewSet
view.py文件,ModelViewSet用的不是query_set而是queryset,需要改下:

url要做稍微的调整,ModelViewSet用的是pk,还得把id改为pk:

好的其他不用作任何更改
访问:

添加:


修改:


删除:

数据库里已经没有id为7的

是的,就是这么方便
全部代码:
url:
from django.urls import path, re_path, include
# from demo1.views import BookView, BookEditView, BookModelViewSet
from demo1.views import BookModelViewSet
urlpatterns = [
path('list', BookModelViewSet.as_view({'get': 'list', 'post': 'create'})),
path('retrieve/<int:pk>', BookModelViewSet.as_view({'get': 'retrieve',
'put': 'update',
'delete': 'destroy'})),
]
view:
# coding:utf-8
from demo1 import models
from demo1.serializers import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer
当然,如果你还是想用自己定义那些方法类,可以这样:

全部代码:相关的类名做了稍微的调整
# coding:utf-8
from django.shortcuts import HttpResponse
from django.views import View
from demo1 import models
from django.core import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from demo1.serializers import BookSerializer
from rest_framework.viewsets import ViewSetMixin
class GenericAPIView(APIView):
query_set = None
serializer_class = None
def get_queryset(self):
return self.query_set
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
# Mixin字段的都是混合类,需要混合继承
class ListModelMixin(object):
def list(self, request):
book_list = self.get_queryset()
ret = self.get_serializer(book_list, many=True)
return Response(ret.data)
class CreateModelMixin(object):
def create(self, request):
serialize = self.get_serializer(data=request.data)
if serialize.is_valid():
# save是存储
serialize.save()
return Response(serialize.data)
else:
return Response(serialize.errors)
class RetrieveModelMixin(object):
def retrieve(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
ret = self.get_serializer(book_obj)
return Response(ret.data)
class RetrieveUpdateModelMixin(object):
def update(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
# partial参数表示只对部分数据验证
serialize = self.get_serializer(book_obj, data=request.data, partial=True)
if serialize.is_valid():
serialize.save()
return Response(serialize.data)
else:
return Response(serialize.errors)
class RetrieveDestoryModelMixin(object):
def destroy(self, request, id):
book_obj = self.get_queryset().filter(id=id).exists()
if not book_obj:
return Response('不存在id为%s的数据,请重试' % id)
else:
self.get_queryset().filter(id=id).delete()
return Response("删除成功")
class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, RetrieveUpdateModelMixin,
RetrieveDestoryModelMixin):
pass
class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
pass
class BookView(ListCreateAPIView):
query_set = models.Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class BookEditView(RetrieveUpdateDestroyAPIView):
query_set = models.Book.objects.all()
serializer_class = BookSerializer
def get(self, request, id):
return self.retrieve(request, id)
def put(self, request, id):
return self.update(request, id)
def delete(self, request, id):
return self.destroy(request, id)
class ModelViewSet(ViewSetMixin, ListModelMixin, CreateModelMixin, RetrieveUpdateModelMixin, RetrieveModelMixin,
RetrieveDestoryModelMixin):
pass
class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer
自定义方法类
视图组件完毕!
然后,有些东西是需要看源码才能看懂的,相关的源码查看:
from rest_framework import views from rest_framework import generics from rest_framework import mixins from rest_framework import viewsets
整个逻辑示图:

前后端分离djangorestframework——视图组件的更多相关文章
- 前后端分离djangorestframework——路由组件
在文章前后端分离djangorestframework——视图组件 中,见识了DRF的视图组件强大,其实里面那个url也是可以自动生成的,就是这么屌 DefaultRouter urls文件作如下调整 ...
- 前后端分离djangorestframework——分页组件
Pagination 为什么要分页也不用多说了,大家都懂,DRF也自带了分页组件 这次用 前后端分离djangorestframework——序列化与反序列化数据 文章里用到的数据,数据库用的my ...
- 前后端分离djangorestframework——认证组件
authentication 认证是干嘛的已经不需要多说.而前后端未分离的认证基本是用cookie或者session,前后端分离的一般用token 全局认证 先创建一个django项目,项目名为drf ...
- 前后端分离djangorestframework——ContentType组件表
ContentType ContentType其实django自带的,但是平时的话很少会用到,所以还是放在Djangorestframework这个部分 作用: 在实际的开发中,由于数据库量级大,所以 ...
- 前后端分离djangorestframework——权限组件
权限permissions 权限验证必须要在认证之后验证 权限组件也不用多说,读了源码你就很清楚了,跟认证组件很类似 具体的源码就不展示,自己去读吧,都在这里: 局部权限 设置model表,其中的ty ...
- 前后端分离djangorestframework—— 在线视频平台接入第三方加密防盗录视频
加密视频 在以后的开发项目中,很可能有做在线视频的,而在线视频就有个问题,因为在线播放,就很有可能视频数据被抓包,如果这个在线视频平台有付费视频的话,这样就会有人做点倒卖视频的生意了,针对这个问题,目 ...
- 前后端分离djangorestframework—— 接入第三方的验证码平台
关于验证码部分,在我这篇文章里说的挺详细的了:Python高级应用(3)—— 为你的项目添加验证码 这里还是再给一个前后端分离的实例,因为极验官网给的是用session作为验证的,而我们做前后端分离的 ...
- 前后端分离djangorestframework——序列化与反序列化数据
我们写好后端的代码,要把数据交给前端的展示的,这个数据以什么类型给前端呢?学到这里,我们已经知道这个数据最好是json字符串才行,因为网络间的传输,只认字符串或者二进制,字符串就是我们的数据,二进制就 ...
- 前后端分离djangorestframework——restful规范
restful现在非常流行,所以很有必要提一下 web服务交互 在浏览器中能看到的每个网站,都是一个web服务.那么我们在提供每个web服务的时候,都需要前后端交互,前后端交互就一定有一些实现方案,我 ...
随机推荐
- jvm详情——1、堆中存什么?栈中存什么?
数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身, ...
- 32位汇编第五讲,逆向实战干货,(OD)快速定位扫雷内存.
32位第五讲,逆向实战干货,快速定位扫雷内存. 首先,在逆向之前,大家先对OD有一个认识. 一丶OD的使用 标号1: 反汇编窗口 (显示代码的地址,二进制指令,汇编代码,注释) 标号2: 寄存器窗口( ...
- spring学习(一) ———— IOC讲解
spring基本就两个核心内容,IOC和AOP.把这两个学会了基本上就会用了. --WH 一.什么是IOC? IOC:控制反转,通俗点讲,将对象的创建权交给spring,我们需要new对象,则由spr ...
- The 2018 ACM-ICPC Asia Qingdao Regional Contest(部分题解)
摘要: 本文是The 2018 ACM-ICPC Asia Qingdao Regional Contest(青岛现场赛)的部分解题报告,给出了出题率较高的几道题的题解,希望熟悉区域赛的题型,进而对其 ...
- 基于SpringMVC+Spring+MyBatis实现秒杀系统【客户端交互】
前言 该篇主要实现客户端和服务的交互.在第一篇概况里我已经贴出了业务场景的交互图片. 客户端交互主要放在seckill.js里来实现.页面展现基于jsp+jstl来实现. 准备工作 1.配置web.x ...
- Ubuntu使用(一)——常用命令与软件安装配置
1.安装输入法 2.配置JDK 3.eclipse 3.1 eclipse启动错误 修改eclipse.init的配置,主要加-vm以及下面的jre路径,路径前别留空格 之前因为加了空格,一直找不到原 ...
- JSTL_Format标记库
JSTL_Format 一:JSTL Format标记库 如有转载,请标明出处 介绍标记属性的时候,按照顺序必须写的->带有默认值的->其他的,中间用回车隔开 在jsp问价开头加上 < ...
- 改变eclipse默认的Tomcat部署路径
eclipse中默认的项目部署路径是在项目的路径,不像myeclipse那样部署后项目在Tomcat的安装路径webapps下.这样虽然可以运行,但是不方便开发和调试,本文将介绍如何改变eclipse ...
- angular 分页插件的使用
html: <pagination total-items="totalItems" ng-model="currentPage" items-per-p ...
- vuejs通过filterBy,orderBy实现搜索筛选,降序排序数据实例
直接贴代码了: 先上输入前的样子: <style> #example{margin:100px auto;width:600px;} .show{margin:10px;} #search ...