Django-DRF-视图的演变

 

版本一(基于类视图APIView类)

views.py:

APIView是继承的Django View视图的。

 1 from .serializers import UserSerializers    #导入当前目录配置好的序列化器
2 from .models import User #导入数据库
3 from rest_framework.views import APIView #导入APIView
4 from rest_framework.response import Response #该模块返回json数据
5 from rest_framework import status #内置状态码模块
6
7 class UserAPIView(APIView): #查看所有及添加数据视图
8 def get(self,request):
9 users = User.objects.all() #获取数据库里所有数据
10 ser = UserSerializers(instance=users,many=True) #进行序列化操作,指定更多集合对象
11 return Response(ser.data,status=200)#返回成功数据
12
13 def post(self,request): #添加数据
14 ser = UserSerializers(data=request.data)#接收前台传输数据
15 if ser.is_valid(): #判断书否合法raise_exception=True加次参数表示不合法抛出异常,默认false
16 ser.save() #保存
17 return Response(ser.data,status=200)
18 return Response(ser.errors) #返回错误信息
19
20 class UserSingleView(APIView): #单条查询,改,删除视图
21 def get(self,request,pk):
22 user = User.objects.get(id=pk) #查询单条集合对象
23 ser = UserSerializers(instance=user)#序列化数据
24 return Response(ser.data)
25
26 def put(self,request,pk): #修改
27 user = User.objects.get(pk=pk)
28 ser = UserSerializers(instance=user,data=request.data) #注意指定参数
29 if ser.is_valid():
30 ser.save()
31 return Response(ser.data,status=200)
32 return Response(ser.errors)
33
34 def delete(self,request,pk): #删除操作
35 User.objects.get(pk=pk).delete()
36 return Response(status=status.HTTP_200_OK)
代码说明:
1. 使用类视图,定义两个类并继承APIView类视图;
2. 在类视图里编写:增删改查方法,通过HttpResponse返回状态。

serializers.py


from rest_framework import serializers #导入序列

from .models import User #导入表

class UserSerializers(serializers.Serializer):#注意继承的类
nick_name = serializers.CharField(max_length=20,required=True) #required=True设置必须验证
gender = serializers.BooleanField(default=0,required=False)
def create(self, validated_data): #创建数据的操作
return User.objects.create(**validated_data) def update(self, instance, validated_data):#修改数据的操作
     instance接收的是数据库查询的单个对象,validated_data为前端传输的数据

instance.nick_name = validated_data.get('nick_name',instance.nick_name)
instance.gender = validated_data.get('gender',instance.gender)
instance.save()          #取出值每个字段进行保存
return instance

版本二(使用混合 mixins)

继承generics和mixins里的方法,称之为“混合”

views.py:

 1 from rest_framework import mixins, generics  # 导入相应模块
2 # mixins就是一个类,只不过这个类里定义了很多操作数据的方法
3 from .serializers import UserModelSerializer
4 class UserGenericAPIview(generics.GenericAPIView,mixins.ListModelMixin,mixins.CreateModelMixin):
5 queryset = UserInfo.objects.all() # queryset指定集合数据是从哪个数据库来
6 serializer_class =UserModelSerializer # serializer_class配置序列化器类UserModelSerializer
7
8 # 调用mixins.ListModelMixin类的list()方法
9 def get(self,request):
10 return self.list(request)
11
12 # 调用mixins.CreateModelMixin类的create()方法
13 def post(self,request):
14 return self.create(request)
15
16 class UserGenericSingleView(generics.GenericAPIView,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin):
17 queryset = UserInfo.objects.all()
18 serializer_class = UserModelSerializer
19
20 # 调用mixins.RetrieveModelMixin类的retrieve()方法
21 def get(self,request,pk): #检索
22 return self.retrieve(request)
23
24 # 调用mixins.UpdateModelMixin类的update()方法
25 def put(self,request,pk): #修改
26 return self.update(request)
27
28 # 调用mixins.DestroyModelMixin类的destroy()方法
29 def delete(self,request,pk): #破坏
30 return self.destroy(request)
代码说明:
1. 为什么要继承mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin等这一堆方法呢?
答:比如我们自定义写了delete方法,而这个方法会自动、只能的去调用mixins.DestroyModelMixin这个类里面的动作。

serializers,py

1 from rest_framework import serializers
2 from .models import UserInfo
3
4 class UserModelSerializer(serializers.ModelSerializer):
5 class Meta:
6 #配置model为UserInfo
7 model = UserInfo
8 fields = "__all__" #fields配置要序列化的字段,"__all__"表示所有的字段都序列化

在上个版本中,queryset和serializer属性都是通过自己声明去使用的;

这个版本继承使用混合继承了generics,通过查看generics源码发现如下:

class GenericAPIView(views.APIView):
···
queryset = None
serializer_class = None
···

版本三(使用混合高级版)

views.py:

1 from rest_framework import generics
2
3 class UserListAPIView(generics.ListCreateAPIView):
4 queryset = UserInfo.objects.all()
5 serializer_class = UserModelSerializer
6
7 class UserSingleView(generics.RetrieveUpdateDestroyAPIView):
8 queryset = UserInfo.objects.all()
9 serializer_class = UserModelSerializer

这几行代码搞定上面所有功能,只需要传入queryset和serializer即可,这什么原理呢?

1、第二版本中,我们继承了generics.GenericAPIView类视图,自己写了两个get和post方法对吧,那generics的另一个方法把这两个事情也干了,我们只需要继承即可。
2、对的,这个方法就是generics.ListCreateAPIView,我们且看看它的源码,你就明白了
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)

版本四(视图集 ViewSet)

views.py:

 1 from rest_framework import viewsets,mixins
2 class GennericViewsSet(viewsets.GenericViewSet,
3 mixins.CreateModelMixin,
4 mixins.ListModelMixin,
5 mixins.RetrieveModelMixin,
6 mixins.UpdateModelMixin,
7 mixins.DestroyModelMixin
8 ):
9 queryset = UserInfo.objects.all()
10 serializer_class = Userserializer

这个版本views里就写了一个类视图,之前的所有版本都是写一个List和一个Detail视图的,

这个类 继承了viewsets.GenericViewSet,其他的方法都是mixins的viewsets

GenericViewSet继承了ViewSetMixin方法,从ViewSetMixin的源码里能看到可以改写as_view的信息,来达到定制路由的效果

class ViewSetMixin(object):
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
······
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")

urls.py:

1 from django.conf.urls import url
2 from . import views
3
4 urlpatterns = [
5 url(r'^$',views.GennericViewsSet.as_view({'get':'list',"post": "create"})), #注意这里的写法
6 url(r'^users/(?P<pk>\d+)/$',views.GennericViewsSet.as_view({'get':'retrieve','put':'update','delete':'destroy'}))
7 ]

版本五 (终极大法:写项目选用此法)

views.py:

1 from rest_framework.viewsets import ModelViewSet
2 class ZhongJiBanView(ModelViewSet):
3 queryset = UserInfo.objects.all()
4 serializer_class = UserModelSerializer

直接继承了一个巨无霸(ModelViewSet),这个巨无霸将所有的功能都封装到一块。相当于把我们从第一版到第三版写的所有事情都干了,

按照老规矩,我们来看看它的源码:

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

从源码中能看出,ModelViewSet所继承的视图类

urls.py

1 from . import views
2 from rest_framework.routers import DefaultRouter
3 rount = DefaultRouter()
4 rount.register('user',views.ZhongjiBanView)
5 urlpatterns = []
6 urlpatterns += rount.urls

最终版的规则使用了drf的DefaultRouter函数,通过实例化DefaultRouter得到route对象,使用route.register()你的app路由,有多个注册多个即可

转载附上博主链接:https://www.cnblogs.com/gaosai/

作者:高赛

Django-DRF-视图的演变(二)的更多相关文章

  1. Django:视图views(二)

    把request对象和response对象原理流程写一下 request对象 服务器端接收到http协议的请求,会根据报文信息构建HttpRequest对象 通过第一个参数,把该对象传递给视图函数 R ...

  2. Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器

    一.视图层封装 二.ViewSetMixin 三.路由配置 四.解析器 五.响应器 一.视图层封装 1.基本视图 写一个出版社的增删改查resfull接口 路由: url(r'^publish/$', ...

  3. DRF 视图

    目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py ...

  4. DRF 视图组件

    目录 DRF 视图组件 视图组件大纲 两个视图基本类 五个扩展类 九个子类视图 视图集 常用视图集父类 魔法类 一览表 DRF中视图的"七十二变" 第一层:基于APIview的五个 ...

  5. DRF JWT认证(二)

    快速上手JWT签发token和认证,有这一篇就够了,DRF自带的和自定义的都帮你总结好了,拿去用~

  6. Django 系列博客(二)

    Django 系列博客(二) 前言 今天博客的内容为使用 Django 完成第一个 Django 页面,并进行一些简单页面的搭建和转跳. 命令行搭建 Django 项目 创建纯净虚拟环境 在上一篇博客 ...

  7. Django通用视图APIView和视图集ViewSet的介绍和使用

    原 Django通用视图APIView和视图集ViewSet的介绍和使用 2018年10月21日 14:42:14 不睡觉假扮古尔丹 阅读数:630   1.APIView DRF框架的视图的基类是 ...

  8. 解决Django + DRF:403 FORBIDDEN:CSRF令牌丢失或不正确,{"detail":"CSRF Failed: CSRF cookie not set."}

    我有一个Android客户端应用程序尝试使用Django + DRF后端进行身份验证.但是,当我尝试登录时,我收到以下响应: 403: CSRF Failed: CSRF token missing ...

  9. Django的视图响应类型

    Django的视图响应类型 一. 视图函数编写原则 视图函数接受HTTP请求并返回响应,可以放在任何地方,可以是任何功能:视图函数可以返回Web文本,页面.重定向.错误.图片等任何内容:视图函数通过H ...

  10. Django 定义视图函数

    Django 定义视图函数 一.接收内容及文件处理 1.接收分类 # 获取数据 request.GET # 提交数据 request.POST # 获取文件 request.FILES 2.check ...

随机推荐

  1. 数据结构之双端队列(Deque)

    1,双端队列定义 双端队列:其两端都可以入列和出列的数据结构,如下图所示,队列后面(rear)可以加入和移出数据,队列前面(front)可以加入和移出数据 双端队列操作: deque=Deque() ...

  2. 负载均衡 | Nginx+Tomcat 动静分离实现负载均衡

    0.前期准备 使用Debian环境.安装Nginx(默认安装),一个web项目,安装tomcat(默认安装)等. 1.一份Nginx.conf配置文件 基本配置这个文件,就可以实现负载了.但是里面的各 ...

  3. 提高组刷题班 DAY 1 上午

    低仿机器人(robo,1s,64M) 题解 大模拟 代码 #include <cstdio> #include <cstring> #include <iostream& ...

  4. SQL:目录

    ylbtech-SQL:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.c ...

  5. 用key管理可复用元素

    先看看不用key管理可复用元素的代码.Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染.这么做,除了使 Vue 变得非常快之外,还有一些有用的好处,那就是在切换input时不会清楚 ...

  6. selenium操作cookie

    1,登录网页,使用webdriver的get_cookies获取cookie,并保存json文件 2,读取json文件,遍历添加网站使用的每一个cookies的name,value. 使用add_co ...

  7. [转]Java Jacob操作Excel

    Jacob项目:https://sourceforge.net/projects/jacob-project/ 转自:https://blog.csdn.net/ZY_extreme/article/ ...

  8. php curl如何设置自定义请求头和打印请求头信息

    $header = [ 'client:h5', 'token:test', ]; curlRequest($url, $params, true, 10, $header); PHP5.1.3版以上 ...

  9. Java类的加载及初始化

    每个类的编译代码都存在于它自己的独立文件中,该文件在需要使用该程序代码时才会被加载.通常有以下三种加载情况: (1) 访问了子类的静态变量或静态方法:仅对类的静态变量,静态块执行初始化操作,并仅初始化 ...

  10. 树莓派(Linux)添加USB外接硬盘

    1.显示系统的硬盘设备以及分区 sudo fdisk -l 显示设备名,例如/dev/sda1 2.树莓派默认不支持NTFS文件系统,如果需要支持则要安装相应的软件包 sudo apt-get ins ...