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

views.py:

APIView是继承的Django View视图的。

 from .serializers import UserSerializers    #导入当前目录配置好的序列化器
from .models import User #导入数据库
from rest_framework.views import APIView #导入APIView
from rest_framework.response import Response #该模块返回json数据
from rest_framework import status #内置状态码模块 class UserAPIView(APIView): #查看所有及添加数据视图
def get(self,request):
users = User.objects.all() #获取数据库里所有数据
ser = UserSerializers(instance=users,many=True) #进行序列化操作,指定更多集合对象
return Response(ser.data,status=200)#返回成功数据 def post(self,request): #添加数据
ser = UserSerializers(data=request.data)#接收前台传输数据
if ser.is_valid(): #判断书否合法raise_exception=True加次参数表示不合法抛出异常,默认false
ser.save() #保存
return Response(ser.data,status=200)
return Response(ser.errors) #返回错误信息 class UserSingleView(APIView): #单条查询,改,删除视图
def get(self,request,pk):
user = User.objects.get(id=pk) #查询单条集合对象
ser = UserSerializers(instance=user)#序列化数据
return Response(ser.data) def put(self,request,pk): #修改
user = User.objects.get(pk=pk)
ser = UserSerializers(instance=user,data=request.data) #注意指定参数
if ser.is_valid():
ser.save()
return Response(ser.data,status=200)
return Response(ser.errors) def delete(self,request,pk): #删除操作
User.objects.get(pk=pk).delete()
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:

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

serializers,py

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

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

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

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

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

views.py:

 from rest_framework import generics

 class UserListAPIView(generics.ListCreateAPIView):
queryset = UserInfo.objects.all()
serializer_class = UserModelSerializer class UserSingleView(generics.RetrieveUpdateDestroyAPIView):
queryset = UserInfo.objects.all()
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:

 from rest_framework import viewsets,mixins
class GennericViewsSet(viewsets.GenericViewSet,
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin
):
queryset = UserInfo.objects.all()
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:

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

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

views.py:

 from rest_framework.viewsets import ModelViewSet
class ZhongJiBanView(ModelViewSet):
queryset = UserInfo.objects.all()
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

 from . import views
from rest_framework.routers import DefaultRouter
rount = DefaultRouter()
rount.register('user',views.ZhongjiBanView)
urlpatterns = []
urlpatterns += rount.urls

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

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

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

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

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

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

  3. DRF视图-请求与响应

    DRF视图 drf的代码简写除了在数据序列化体现以外,在视图中也是可以的.它在django原有的django.views.View类基础上,drf内部封装了许多子类以便我们使用. Django RES ...

  4. DRF视图组件

    DRF视图组件: CVB模式继承----五层 from django.views import View # Django的View from rest_framework.views import ...

  5. drf 视图使用及源码分析

    前言 drf视图的源码非常的绕,但是实现的功能却非常的神奇. 它能够帮你快速的解决ORM增删改查的重复代码,非常的方便好用. 下面是它源码中的一句话: class ViewSetMixin: &quo ...

  6. django DRF理解

    django restframework(DRF) 最近的开发过程当中,发现restframework的功能很强大,所以尝试解读了一下源码,写篇博客分享给大家,有错误的地方还请各位多多指出 视图部分 ...

  7. Django DRF 分页

    Django DRF 分页 分页在DRF当中可以一共有三种,可以通过setttings设置,也可也通过自定义设置 PageNumberPagination 使用URL http://127.0.0.1 ...

  8. DRF 视图组件

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

  9. 【Django】 视图层说明

    [Django视图层] 视图层的主要工作是衔接HTTP请求,Python程序和HTML模板,使他们能够有机互相合作从模型层lou到数据并且反馈.说到视图层的工作就有以下几个方面要说 ■ URL映射 对 ...

  10. Django基本视图

    Django基本视图 下面这三个类也许不能提供项目所需的所有的功能,这些应用于基于类的视图或Mixins情形下. 大多数Django的内建视图继承于其他基于类的视图或者各种mixins中,因为继承链是 ...

随机推荐

  1. javascript中defer的作用

    javascript中defer的作用 <script src="../CGI-bin/delscript.js" defer></script>中的def ...

  2. CentOS Linux最常用命令及快捷键整理

    最近一直在对CentOS系统进行各种体验,为方便自己也方便他人,整理了Linux常用命令及快捷键,不过其实大多和DOS是一样的,只是命令的表达上可能有点儿不一样. 常用Linux命令: 文件和目录: ...

  3. SO_LINGER

    [SO_LINGER] 在默认情况下,当调用close关闭socket的使用,close会立即返回,但是,如果send buffer中还有数据,系统会试着先把send buffer中的数据发送出去,然 ...

  4. 使用net Manager工具配置远程连接oracle

    一,在服务端配置oracle端口在命令行中输入netca命令,打开相关配置默认端口号为1521 二,配置端口后使用Telnet工具调试端口是否联通 在命令行输入telnet 服务器ip 端口号 三,找 ...

  5. 5-math中函数汇总

    math.h 数学函数库,一些数学计算的公式的具体实现是放在math.h里,具体有:1 三角函数double sin (double);double cos (double);double tan ( ...

  6. Laravel 使用 seeder 使用要点

    一.关于 DB use DB; 再使用 DB::table(database.table)->get(); 二.关于 ERROR 1366 (HY000): Incorrect string v ...

  7. [原创]使用OPENCC库进行简繁转换(C++代码)

    最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...

  8. C# Redis Server分布式缓存编程(一)(转)

    出处:http://www.cnblogs.com/davidgu/p/3262571.html 这篇文章我将介绍如果用最简洁的方式配置Redis Server, 以及如何使用C#和它交互编程 一. ...

  9. 优秀前端工程师必备: 我要一个新窗口: js开新窗的2种姿势

    1.<a href="https://www.cnblogs.com/" title="博客园">当前页面打开博客园</a> js代码等 ...

  10. os.path等os模块函数

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...