视图类与视图集的基本使用

视图类与视图集的使用

一、视图类:View、APIView、GenericAPIView

View是Django提供的一个视图类,类的返回值需要用到HttpResponse、JSONResponse

(一)、APIView

继承自Django中定义的View,但和View有两个区别:

  • 返回数据用到的是drf框架中的Response
  • 对数据的处理上,可以通过query_params来代替GET,data来代替POST
# 创建加密分页类
class MyCursorPagination(CursorPagination):
    cursor_query_param = ‘cursor‘
    page_size = 2
    max_page_size = 4
    max_page_size_param = ‘size‘
    page_param = ‘cursor‘
    ordering = ‘id‘
    # 注意:加密分页类和其他的两个类的一个不同点在于,该类分页时需要排序,ordering = ‘字段’

class APIView1(APIView):
    # 获取所有的数据
    def get(self, request, *args, **kwargs):
        role_obj = Role.objects.all()
        pg = MyCursorPagination()
        page = pg.paginate_queryset(queryset=role_obj, request=request, view=self)
        serializer = Page2Serializer(instance=page, many=True)
        return pg.get_paginated_response(serializer.data)

    # 在数据库中创建一条数据
    def post(self, request, *args, **kwargs):
        data_dict = request.data
        serializer = Page2Serializer(data=data_dict)
        result = serializer.is_valid(raise_exception=True)
        if result:
            serializer.save()
            # 创建和更新数据必须写.save()方法
            return Response(serializer.validated_data)

class APIView2(APIView):
    # 获取一条数据
    def get(self, request, pk):
        role_obj = Role.objects.get(pk=pk).first()
        serializer = Page2Serializer(instance=role_obj)
        return Response(serializer.data)

    # 更新一条数据
    def put(self, request, pk):
        data_dict = request.data
        serializer = Page2Serializer(data=data_dict)
        result = serializer.is_valid(raise_exception=True)
        # 注意:更新和创建都是反序列化操作,必须接收数据后进行数据的校验,然后再进行存储
        if result:
            serializer.save()
        return Response(serializer.validated_data)

    # 删除一条数据
    def delete(self, request, pk):
        role_obj = Role.objects.filter(pk=pk)
        role_obj.delete()
        return Response("删除成功")

(二)、GenericAPIView

GenericAPIView继承自APIView,和APIView的区别在于需要把用到的数据集和需要用到的组件中的类作为全局变量定义在视图类中使用。

# Create your views here.
class TestGenericAPIView(GenericAPIView):
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer1
    pagination_class = PageNumberPagination
    # GenericAPIView与APIView和View的区别在与需要把实例化的数据集queryset和视图中要用到的组件类必须在方法前进行声明,作为全局变量来使用,在类方法中再进行调用
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        pg = self.paginate_queryset(queryset=queryset)
        serializer = self.get_serializer(instance=pg, many=True)
        return Response(serializer.data)
        # GenericAPIView继承自APIView类,通过generic.py文件中的源码可以看出,该类封装了很多的方法,通过在类中定义的全局变量作为参数传递给类中的具体点方法,这些方法也只是返回获取到的类,并未对分页、序列化器等进行处理,这个功能的实现还是需要自己来来进行。和APIView没有太大的区别。

二、视图集的使用:GenericViewSet、ModelViewSet

Note

视图集的使用上和视图类有一个很重要的区别:视图集中可以自定义处理方法名,这些方法名必须声明在as_view({‘request方式‘:‘方法名‘})内。视图集解决了视图类中的两个问题:

  • 请求方式冲突的问题:在视图集中get请求既是获取所有的数据,即数据列表,也是获取单条数据,即数据详情,容易造成混乱
  • url冲突:在视图类中有pk和没有pk参数的处理类是不同的,需要用到两个视图类,为两个类分别创建url,视图集中只需要创建一个视图类即可解决,并且视图集的使用中可以调用Router类来管理url,很好的解决了url的混乱问题。
(一)、GenericViewSet类的使用

该类继承自GenericAPIView和ViewSetMxixin两个类, 具有GenericAPIView中的所有属性和方法,同样也需要去通过self去获得所有的类和queryset,如果希望直接使用增删改查中的一些方法,则需要单独继承Mixins扩展中的类, 这些类在继承上必须优于GenericAPIView;如果不继承扩展类,则必须自定义处理方法

from rest_framework.viewsets import GenericViewSet
from rest_framework.pagination import CursorPagination
class MyPagination(CursorPagination):
    page_size = 1
    page_param = ‘page‘
    max_page_size = 5
    max_page_size_param = ‘size‘
    ordering = ‘id‘
    cursor_query_param = ‘cursor‘

# 自定义处理方法
class GenericViewSet1(GenericViewSet):
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer1
		# pagination_class = PageNumberPagination
    pagination_class = MyPagination
    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        pg = self.paginate_queryset(queryset=queryset)
        serializer = self.get_serializer(instance=pg, many=True)
        data = pg.get_paginated_response(serializer.data)
        # GenericAPIView中所有的用法在该类中同样继承下来
        return data
# 继承扩展类
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.viewsets import GenericViewSet
class View3View(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
    queryset = Role.objects.all()
    serializer_class = Page2Serializer
    pagination_class = LimitOffsetPagination

(二)、ModelViewSet视图集的使用

Note

ModelViewSet类的使用中需要注意的是:一旦继承该类,在视图类中就不需要自定义request的请求方法, 该类把增删改查等基本的处理方法已经封装好了,直接继承Mixins扩展中的五个类,可以直接使用。优点是方便简介,可以直接使用。缺点是该类封装类绝大部分的方法,只有这些接口都需要用到的时候这个类才是最优选择,该类的可定制性不高。

--serializers.py
class Page2Serializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    def validate(self, data):
        id = data.get(‘id‘)
        title = data.get(‘title‘)
        return data
    # 若要执行创建和更新的操作,必须先从验证过的数据中获取对应的信息,然后再执行操作。
    def create(self, validated_data):
        id = validated_data.get(‘id‘)
        title = validated_data.get(‘title‘)
        instance = Role.objects.create(id=id, title=title)
        instance.save()
        return instance
    def update(self, instance, validated_data):
        id = validated_data.get(‘id‘)
        title = validated_data.get(‘title‘)
        instance = Role.objects.filter(id=id).first()
        instance.id = id
        instance.title = title
        instance.save()
        return instance
‘‘‘
需要特别注意的是:当序列化类继承的是Serializer的时候,除了字段验证之外,必须写上create和update饭方法,
‘‘‘
--views.py
class View2View(ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = Page2Serializer
    pagination_class = PageNumberPagination 

因为基类中虽然有两个方法,但是都是pass,如果不重写两个方法,系统就是报错无法正常运行

三、Mixin的五个扩展类

  • ListModelMixin:这个扩展类的功能是获取数据列表
  • RetrieveModelMixin :这个扩展类的功能是获取某一条数据详情
  • CreateModelMixin : 这个扩展类的功能是在数据库中创建一条数据
  • UpdateModelMixin: 这个扩展类的功能是在数据库中更新一条数据
  • DestroyModelMixin:这个扩展类的功能是从数据库中删除指定的一条数据

四、视图类和视图集的关系图

Note

越是封装内容多的类,可定制性、灵活性越差,功能越全面,越是基类可定制性越高,但很多的方法和功能需要开发者定义

graph TB
A[视图]-->B[视图类]
B[视图类]-->C[Django框架下的View]
C{Django框架下的View}--特性1-->D[接收参数和数据GET/POST方式]
C{Django框架下的View}--特性2-->E[返回方式HttpResponse/JSONResponse/Render/Redirect]
C{Django框架下的View}--继承自-->F{APIView}
F{APIView}--特性1-->G[数据接收query_prames代替GET,data代替POST]
F{APIView}--特性2-->H[返回方式Response,对数据进行渲染]
F{APIView}--继承自-->I{GenericAPIView}
I{GenericAPIView}--特性1-->J[queryset和需要用到的组件类必须作为全局变量声明方法之间]
I{GenericAPIView}--特性1-->K[组件功能的实现依然需要再方法中具体写出,与APIView没有太大的区别]
A[视图]-->L[视图集]
I{GenericAPIView}--继承自-->L{视图集}
L{视图集}--特性1-->M[继承了GenericAPIView的所有特性]
L{视图集}--特性2-->N[as_View区分处理request的方法名]
L{视图集}-->O{GenericAPIView}
O{GenericViewSet}--继承自-->Q[ViewSetMixin]
O{GenericViewSet}--继承自-->R[GenericAPIView]
O{GenericViewSet}-->S{使用中继承先继承ViewSetMixin中的类,再继承R}
S{使用中继承先继承ViewSetMixin中的类,再继承R}--只继承R-->T[在视图类中必须自定义处理的方法]
S{使用中继承先继承ViewSetMixin中的类,再继承R}--两者都继承-->U[不需要定义方法,只把全局变量写好即可]
S{使用中继承先继承ViewSetMixin中的类,再继承R}--继承自-->V{ModelViewSet}
V{ModelViewSet}--特性1-->W[只需继承ModelViewSet类]
V{ModelViewSet}--特性1-->X[继承类后,不需要写方法,所有的方法都已经封装]
V{ModelViewSet}--缺点-->Y[所有的方法都封装,不能自定义]
F{APIView}--优点-->Z[可以很好的根据需求进行自定义]

原文地址:https://www.cnblogs.com/ddzc/p/12152992.html

时间: 2024-10-06 20:52:04

视图类与视图集的基本使用的相关文章

网站后端_Python+Flask.0010.FLASK即插视图之自定义视图类及视图修饰?

即插视图; 说明: FLASK的视图灵感来自于DJANGO的基于类而非基于函数的通用视图,主要目的是为了解决多个视图函数之间已经实现的部分,通过类继承的方式继承到其它视图,总之为了一点,就是少写代码,然后通过add_url_rule让我们定义的视图类支持动态插入,也就是所谓的即插视图 深入视图: # 转换前: #!/usr/bin/env python # -*- coding: utf-8 -*- """ # # Authors: limanman # 51CTOBG: h

二次封装Response类、views:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集

## 二次封装Response类 Response({ 'status': 0, 'msg': 'ok', 'results': [], 'token': '' # 有这样的额外的key-value数据结果 },status=http_status,headers=headers,exception=True|False) APIResponse() => Response({'status': 0,'msg': 'ok'}) """ ``` from rest_fra

DRF ---- 视图类 数据工具类 工具视图集 视图集

目录 一. 视图类 1. ApiView 2. GenericAPIView get_queryset 配置queryset get_object 配置 lookup_url_kwarg get_serializer 配置 serializer_class GenericAPIView配置 结合使用: 二.视图工具类 1)ListModelMixin 群查 2)CreateModelMixin 单增 3) RetrieveModelMixin 单查 4)UpdateModelMixin 单改 5

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类.指定数据库连接字符串以及创建一个数据库.最后,我们还将添加视图和控制器来管理和显式产品和分类数据. 注意:如果你想按照本章的代码编写示例,你必须完成第一章或者直接从www.apress.com下载第一章的源代码. 2.1 添加模型类 Entity Framework的代码优先模式允许我们从模型类创

drf之视图类与路由

视图 Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 2个视图基类 APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父类. APIView与View的不同之处在于: 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象: 视图方法

MFC如何在CMainFrame类中访问CxxxView视图类中的成员

在视图类中,我们可以通过调用AfxGetMainWnd()函数得到框架窗口的指针. 注意,需要在view类实现部分添加#include "MainFrm.h". 1 CMainFrame* pMFram = (CMainFrame*)AfxGetMainWnd(); 如果想在框架窗口中想调用CxxxView类中的函数,也需要得到相应View视图类的指针. 但是需要注意,这里不仅得包含xxxView.h,还需要包含xxxDoc.h头文件, 还需要注意头文件的顺序,先包含Doc.h,再包含

Django——基于类的视图(class-based view)

刚开始的时候,django只有基于函数的视图(Function-based views).为了解决开发视图中繁杂的重复代码,基于函数的通用视图( Funcation-based generic views)出现了,但是不久它的弊端就显示出来:无法扩展.无法定制.基于函数的通用视图的不灵活导致它在现实世界中的应用受限.基于类的通用视图也是出于同样的目的被开发出来,它提供一个工具箱(基类)并支持多重继承,随着它的应用,人们发现它的可扩展性和灵活性远超它的小兄弟——基于函数的通用视图. 基于类的通用视

织梦解析模板之灵活应用视图类

初步对织梦cms进行了解,忍不住要动手试一试了.织梦cms也是采用mvc的设计模式,它的核心代码,大部分存在于include目录里.包括控制器. 模型.视图类.模板引擎.标签库.公用函数等.下面我们就简单的创建一个属于自己的php页面处理文件,在文件里,用织梦自身的模板引擎和视图,去解析我预先创建好的静态html文件.在此,我简单的写了如下几段代码: 第一步,创建自己的php页面处理文件,在这里,我在根目录下创建demo.php文件,文件内容如下: ? 1 2 3 4 5 6 7 8 9 10

视图层和视图类 、 绘制

1 绘制基本图形 1.1 问题 IOS中进行绘制比较方便,只需要在视图类(UIView及其子类)中重写drawRect方法,将绘制代码要写在该方法中即可,此方法会在视图显示前自动调用.本案例重写视图类中的drawRect方法,绘制一个简单的图形,如图-1所示: 图-1 1.2 方案 首先在创建好的Xcode项目中创建一个TRMyView类,继承至UIView.在Storyboard中拖放一个View控件,在右边栏的检查器中将View和TRMyView类进行绑定,并将背景设置为紫色. 然后在TRM