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. Java-CAS 与原子类

    CAS(Compare and Swap),即比较并替换,实现并发算法时常用到的一种技术. CAS 的思想很简单:三个参数,一个当前内存值 V.旧的预期值 A.即将更新的值 B,当且仅当预期值 A 和 ...

  2. Golang 空指针nil的方法和数据成员

    golang中,有一个特殊的指针值nil. 如何使用nil没有方法和成员变量呢? 下面来看下具体例子. 程序中,定义结构体类型Plane, 将Plane类型的指针作为函数的参数,然后传入nil作为实参 ...

  3. 互斥锁lock、信号量semaphore、事件Event、

    1.互斥锁lock 应用在多进程中互斥所lock:互斥锁是进程间的get_ticket互相排斥进程之间,谁先枪占到资源,谁就先上锁,等到解锁之后,下一个进程在继续使用.# 语法: 上锁: lock.a ...

  4. 一百一十四:CMS系统之图形验证码生成

    安装Pillow库,用于生成图形验证码:pip install Pillow 字体文件来源 生成一个验证码图片 import randomimport stringfrom PIL import Im ...

  5. k8s-高可用多主master配置

    准备主机 centos7镜像 node1: 192.168.0.101 node2: 192.168.0.102 node3: 192.168.0.103 vip: 192.168.0.104 配置s ...

  6. django中CBV加csrf_exempt函数问题

    CSRF Token相关装饰器在CBV只能加到dispatch方法上 备注: 1. csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件. 2. c ...

  7. 20190722 - Windows 下使用 move 命令和通配符移动多个文件

    这是个标题党,实际上 move 命令无法移动通配符匹配的多个文件 比如,我有四个文件: c:\a\a1.txt c:\a\a2.txt c:\a\b1.txt c:\a\b2.txt 想移动后两个文件 ...

  8. python3 速查参考- python基础 7 -> 函数编程之 装饰器、生成器

    装饰器 1.速查笔记 #-- 函数装饰器:是它后边的函数的运行时的声明 由@符号以及后边紧跟的"元函数"(metafunction)组成 @staticmethod def sme ...

  9. LeetCode.1217-交换芯片(Play with Chips)

    这是小川的第次更新,第篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第270题(顺位题号是1217).There are some chips, and the i-th ch ...

  10. LCA cogs 2450 2048 1588

    t1 2450距离 链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=vSNNNVqga [题目描述] 在一个村子里有N个房子,一些双向的路连接 ...