【DRF视图】 -- 2019-08-08 18:01:40

目录

  • 开始使用内置视图

原文: http://106.13.73.98/__/61/

请结合【DRF序列化】此文献中的数据文件及序列化文件来阅读如下代码.

DRF视图为我们提供了非常简便的方法——内置了增删改查等一系列的操作.
我们只需在url中指定对应的方法,视图继承内置方法的类,即可实现两三行代码搞定一个请求.

@
*
我们先看看仿照内置方法实现的**

APIView视图文件:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin

""" ===================== 一层封装 ===================== """

class GenericAPIView(APIView):
    queryset = None
    serializer_class = None

    def get_queryset(self):
        """用于获取queryset的方法"""
        return self.queryset.all()

    def get_serializer(self, *args, **kwargs):
        """用于调用序列化类的方法"""
        return self.serializer_class(*args, **kwargs)

class ListModelMixin():
    """用于返回get请求所有数据的数据"""
    def list(self, request):
        queryset = self.get_queryset()  # self调用的方法(get_queryset)是从执行此方法(list)的当前对象的类中开始找
        ser_obj = self.get_serializer(queryset, many=True)  # 原理同上句话
        return Response(ser_obj.data)

class CreateModelMixin():
    """用于处理post请求发来的数据"""
    def create(self, request):
        ser_obj = self.get_serializer(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.validated_data)
        return Response(ser_obj.errors)

class RetrieveModelMixin():
    """用于返回get请求查询单条数据方法"""
    def retrieve(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        ser_obj = self.get_serializer(book_obj)
        return Response(ser_obj.data)

class UpdateModelMixin():
    """用于处理put请求发来的数据(更新数据)"""
    def update(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.validated_data)
        return Response(ser_obj.errors)

class DestroyModelMixin():
    """用于删除单条数据"""
    def destroy(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        if book_obj:
            book_obj.delete()
            return Response('')
        return Response('The deleted object does not exist.')

""" ===================== 二层封装 ===================== """

class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
    pass

class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    pass

视图文件:

from .custom_mixin import ListCreateAPIView, RetrieveUpdateDestroyAPIView  # 导入上述的APIView视图文件
from DRFView import models
from .serializers import BookSerializer  # 导入自定义的序列化文件

class Book(ListCreateAPIView):
    queryset = models.Book.objects.all()  # 坑:这里的queryset只是放到缓存里了,再次取时还需要用.all()方法
    serializer_class = BookSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)

class BookEdit(RetrieveUpdateDestroyAPIView):
    queryset = 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)


改进版

urls.py文件:

urlpatterns = [
    url(r'^book/$', BookModel.as_view({'get': 'list', 'post': 'create'})),
    url(r'^book/(?P<id>\d+)/$', BookModelView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
"""
注意as_view的传参:
as_view({"请求方式": "调用的方法"}, {...})
指定请求方式调用的方法后,框架会为我们自动执行其方法,无需在CBV中写请求的方法了.
"""

APIView视图文件:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin  # 导入DRF封装好的APIView

""" ===================== 第一层封装 ===================== """

class GenericAPIView(APIView):
    queryset = None
    serializer_class = None

    def get_queryset(self):
        """用于获取queryset的方法"""
        return self.queryset.all()

    def get_serializer(self, *args, **kwargs):
        """用于调用序列化类的方法"""
        return self.serializer_class(*args, **kwargs)

class ListModelMixin():
    """用于返回get请求所有数据的数据"""
    def list(self, request):
        queryset = self.get_queryset()  # self调用的方法(get_queryset)是从执行此方法(list)的当前对象的类中开始找
        ser_obj = self.get_serializer(queryset, many=True)  # 原理同上句话
        return Response(ser_obj.data)

class CreateModelMixin():
    """用于处理post请求发来的数据"""
    def create(self, request):
        ser_obj = self.get_serializer(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.validated_data)
        return Response(ser_obj.errors)

class RetrieveModelMixin():
    """用于返回get请求查询单条数据方法"""
    def retrieve(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        ser_obj = self.get_serializer(book_obj)
        return Response(ser_obj.data)

class UpdateModelMixin():
    """用于处理put请求发来的数据(更新数据)"""
    def update(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.validated_data)
        return Response(ser_obj.errors)

class DestroyModelMixin():
    """用于删除单条数据"""
    def destroy(self, request, id):
        book_obj = self.get_queryset().filter(id=id).first()
        if book_obj:
            book_obj.delete()
            return Response('')
        return Response('The deleted object does not exist.')

""" ===================== 第二层封装 ===================== """

class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
    pass

class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    pass

""" ===================== 第三层封装 ===================== """

class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
# ViewSetMixin重写了as_view方法,即可以传参了.
    pass

视图文件:

from .custom_mixin import ModelViewSet  # 导入上述的APIView视图文件
from DRFView import models
from .serializers import BookSerializer  # 导入自定义的序列化文件

class BookModel(ModelViewSet):
    queryset = models.Book.objects.all()
    # 坑:这里的queryset只是放到缓存里了,再次取时还需要用.all()方法
    # queryset是框架能识别的,会把数据放到缓存中,如果该成其它的名字则不会缓存(比如query),即再此取数据时不能加.all()
    serializer_class = BookSerializer

class BookModelView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

接下来,我们再来看看DRF为我们封装好了的APIView用法。
***

开始使用内置视图

第一步 按照框架的要求写url

urlpatterns = [
    url(r'^book/$', BookModel.as_view({'get': 'list', 'post': 'create'})),
    # 按照APIView的要求,这里必须写为pk,而不能写id
    url(r'^book/(?P<pk>\d+)/$', BookModelView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
"""
注意as_view的传参:
as_view({"请求方式": "调用的方法"}, {...})
指定请求方式调用的方法后,无需在CBV中写请求的方法了.
"""

第二步 写视图文件
```python
from DRFView import models
from .serializers import BookSerializer # 导入自定义的序列化文件
from rest_framework.viewsets import ModelViewSet # 导入DRF封装好的APIView

class BookModel(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer

class BookModelView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer

如上步骤,我们的视图只要写两行就可以了.

关于DRF视图源码解析,推荐参考此文献:https://www.cnblogs.com/GGGG-XXXX/articles/9675911.html

继承顺序图解:


原文: http://106.13.73.98/__/61/

原文地址:https://www.cnblogs.com/gqy02/p/11322794.html

时间: 2024-10-31 13:48:07

【DRF视图】 -- 2019-08-08 18:01:40的相关文章

PTC.Mathcad.Prime.5.0.0.0.Win64 +RAM Connection CONNECT Edition 12.00.01.40

Truth.Concepts.v2.00.0.59 1CD Cadence Allegro and OrCAD 17.20.000-2016 HF045 Update 1DVDCadence Allegro系统互连平台能够跨集成电路.封装和PCB协同设计高性能互连.应用平台的协同设计 方法,工程师可以迅速优化I/O缓冲器之间和跨集成电路.封装和PCB的系统互联.该方法能避免硬件返 工并降低硬件成本和缩短设计周期.约束驱动的Allegro流程包括高级功能用于设计捕捉.信号完整性和 物理实现.由于它

2014/08/08 – Backbonejs

[来自: Backbone.js 开发秘笈 第5章] Event API: (function ($) { //define ------------------------- var obj = {}; var obj2 = { commonEvent: function () { window.document.title = new Date().toString(); } }; //扩展对象包含事件 _.extend(obj, Backbone.Events); _.extend(obj

使用DRF视图集时自定义action方法

在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的: class DepartmentViewSet(ModelViewSet): queryset = Department.objects.all() serializer_class = DepartmentSerializer 现在需要新增一个功能,查询最新成立的部门. 这时,我们就需要自定义action方法了. 新增功能后的代码如下: class D

【DRF视图】

目录 开始使用内置视图 请结合[DRF序列化]此文献中的数据文件及序列化文件来阅读如下代码. DRF视图为我们提供了非常简便的方法--内置了增删改查等一系列的操作. 我们只需在url中指定对应的方法,视图继承内置方法的类,即可实现两三行代码搞定一个请求. @ * 我们先看看仿照内置方法实现的** APIView视图文件: from rest_framework.views import APIView from rest_framework.response import Response fr

DRF视图-请求与响应

DRF视图 drf的代码简写除了在数据序列化体现以外,在视图中也是可以的.它在django原有的django.views.View类基础上,drf内部封装了许多子类以便我们使用. Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 调用请求类和响应类[这两个类也是由drf帮我们再次扩展了一些功能类. 请求与响应 先创建一个子应用req python manage.py startapp httpdemo Reques

原程序员的算法课(1)-算法概述2019年08月18日 17:58:49 十步杀一人_千里不留行 阅读数 11更多所属专栏: 程序员的算法课编辑

[算法之美]数据结构+算法=程序. 前言 数据结构只是静态的描述了数据元素之间的关系.高效的程序需要在数据结构的基础上设计和选择算法. 高效的程序=恰当的数据结构+合适的算法 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一

2019/09/08最新进展

今日完成的工作如下: 1.继续完善论文: 2.发现仿真数据出错了,原来是公式有个地方出错了... 修改后的公式为: (1)      当t1<=2.5s,v=v2 (2)      当2.7s > t1 >2.5s,v = v2 – ug(t^2)/0.4|t=t1-2.5 (3)      当t1>2.7s,  v’=v2-ug(0.2*0.2)-(v1/(ug)+0.1-2.7)*ug 3.根据公式进行仿真.写一个cpp: #include<bits/stdc++.h&g

PAT 甲级 A1019 (2019/02/08)

1 #include<cstdio> 2 bool Judge(int A[], int num){ 3 for(int i = 0; i < num; i++){ 4 if(A[i] == A[num-1-i]) 5 return true; 6 else 7 return false; 8 } 9 } 10 int main(){ 11 int N, b, A[40], num = 0; 12 scanf("%d %d", &N, &b); 13

2019.04.08打卡

1 #include <stdio.h> 2 #include <stdlib.h> 3 typedef int DataType; 4 typedef struct node{ 5 DataType data; 6 struct node *next; 7 }LinkNode,*LinkList; //LinkNode是JAVA中链表结点,此类可以存放int.long.float.double.byte.short.String.StringBuffer类型的数据 8 //定义单