版本一(基于类视图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. (1)activiti认识以及数据库和插件配置

    工作流介绍 工作流(Workflow),就是通过计算机对业务流程自动化执行管理.它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档.信息或任务的过程, 从而实现某个预期的业务目标, ...

  2. 在Centos7下安装Python+Selenium+Firefox学习环境

    Selenium 一自动化测试工具.它支持 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测 ...

  3. 如何在eclipse中添加android ADT(转)

    转自: http://jingyan.baidu.com/article/b0b63dbfa9e0a74a4830701e.html 对于程序开发的学者来说,eclipse并不陌生,它为我们提供了一个 ...

  4. [C++] STL相关面试题

    (1) 为何map和set的插入删除效率比用其他序列容器高? 因为map和set的内部数据结构是红黑树,它的插入和删除不需做内存的拷贝和移动.(红黑树的插入和删除是log(n)的). (2) 为何每次 ...

  5. 07-SSH综合案例:前台用户模块:结构创建及注册页面跳转

    现在就不要直接访问一个JSP,要通过一个Action映射过去.我现在点击要去一个注册的页面 这还不是一个真正的注册,只是一个页面的跳转. 1.5.2 用户模块 注册功能: 在index.jsp页面中点 ...

  6. VMware安装虚拟机Ubuntu提示piix4_smbus 0000:00:007.3: Host SMBus controller not enabled错误解决办法

    安装ubuntu17.10.1虚拟机,遇到了一个问题,就是这个piix4_smbus 0000:00:007.3: Host SMBus controller not enabled. 网上找到了一个 ...

  7. tomcat 403 forbidden

    server.xml和tomcat-users.xml都是设置于过了,还是403,最后发现context.xml中多了一行 <Valve className="org.apache.c ...

  8. WebLogic 12c CentOS7 静默安装

    JDK版本:1.8.0_161 Weblogic版本:12.2.1.3 一.前期准备 1.创建用户和组 # groupadd web # useradd -g web weblogic # passw ...

  9. unix时间戳与时间

    [root@pserver ~]# date -d "@1381371010" Thu Oct :: CST [root@pserver ~]# date --date=" ...

  10. mybatis逆向工程的注意事项:mapper文件内容不是覆盖而是追加

    XXXMapper.xml文件已经存在时,如果进行重新生成则mapper.xml文件内容不被覆盖而是进行内容追加,结果导致mybatis解析失败. 解决方法:删除原来已经生成的mapper xml文件 ...