Django rest framework (视图类详解)

官网:https://www.django-rest-framework.org/api-guide/viewsets/

在django rest framework 视图中一共有N个类

第一类:APIview

class IndexView(APIView):

    def get(self,request,*args,**kwargs):
        pk = kwargs.get(‘pk‘)
        if pk:
            queryset = models.UserInfo.objects.get(pk=pk)
            ser = UserInfoSerializer(instance=queryset,many=False)
        else:
            queryset = models.UserInfo.objects.all()
            ser = UserInfoSerializer(instance=queryset,many=True)
        return Response(ser.data)
#

这种直接继承了APIView,是最原始的。请求方式就是那五种,get,post,put,patch,delete

第二类 GenericAPIView

class IndexView(GenericAPIView):
    queryset = models.UserInfo.objects.all()
    serializer_class = UserInfoSerializer
    lookup_field = ‘pk‘

    def get(self,request,*args,**kwargs):
        pk = kwargs.get(‘pk‘)
        if pk:
            users = self.filter_queryset(queryset=models.UserInfo.objects.get(pk=pk))
            ser = self.get_serializer(instance=users)
        else:
            users = self.get_queryset()
            ser = self.get_serializer(instance=users,many=True)
        return Response(ser.data)

在GenericAPIView中要重写一些字段和方法,不常用。

第三类 GenericViewSet

class IndexView(GenericViewSet):
    serializer_class = UserInfoSerializer
    queryset = models.UserInfo.objects.all()
    def create(self,request,*args,**kwargs):
        pass

    def list(self,request,*args,**kwargs):  # 获取列表数据
        users = models.UserInfo.objects.all()
        ser = UserInfoSerializer(instance=users,many=True)
        return Response(ser.data)

    def retrieve(self,request,*args,**kwargs):  # 获取单条数据
        pk = kwargs.get(‘pk‘)
        users = models.UserInfo.objects.get(pk=pk)
        ser = UserInfoSerializer(instance=users,many=False)
        return Response(ser.data)

    def destroy(self,request,*args,**kwargs):
        pass

    def update(self,request,*args,**kwargs):
        pass

    def partial_update(self,request,*args,**kwargs):
        pass

这个类继承了ViewSetMixin, generics.GenericAPIView,其中在ViewSetMixin中会重写as_view()方法,因此可以将URL中的请求方式与视图函数绑定到一起,在urls.py中以键值对的方式存在:
urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import  views

urlpatterns = [
    # url(r‘^admin/‘, admin.site.urls),
    url(r‘^hehe/‘, views.hehe),
    url(r‘^index/$‘, views.IndexView.as_view({‘get‘:‘list‘,‘post‘:‘create‘})),
    url(r‘^index/(?P<pk>\d+)/$‘, views.IndexView.as_view({‘get‘:‘retrieve‘,‘put‘:‘update‘,‘patch‘:‘partial_update‘,‘delete‘:‘destroy‘})),
]

ViewSetMixin源码部分:

class ViewSetMixin(object):
    """
    This is the magic.

    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.

    For example, to create a concrete view binding the ‘GET‘ and ‘POST‘ methods
    to the ‘list‘ and ‘create‘ actions...

    view = MyViewSet.as_view({‘get‘: ‘list‘, ‘post‘: ‘create‘})
    """

    @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
        """
        Because of the way class based views create a closure around the
        instantiated view, we need to totally reimplement `.as_view`,
        and slightly modify the view function that is created and returned.
        """
        # The suffix initkwarg is reserved for displaying the viewset type.
        # eg. ‘List‘ or ‘Instance‘.
        cls.suffix = None

        # Setting a basename allows a view to reverse its action urls. This
        # value is provided by the router through the initkwargs.
        cls.basename = None

        # actions must not be empty
        if not actions:
            raise TypeError("The `actions` argument must be provided when "
                            "calling `.as_view()` on a ViewSet. For example "
                            "`.as_view({‘get‘: ‘list‘})`")

        # sanitize keyword arguments
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don‘t do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r" % (
                    cls.__name__, key))

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            # We also store the mapping of request methods to actions,
            # so that we can later set the action attribute.
            # eg. `self.action = ‘list‘` on an incoming GET request.
            self.action_map = actions

            # Bind methods to actions
            # This is the bit that‘s different to a standard view
            for method, action in actions.items():
                handler = getattr(self, action)  # 通过反射获取请求方式
                setattr(self, method, handler) # 绑定到视图函数中的方法

            if hasattr(self, ‘get‘) and not hasattr(self, ‘head‘):
                self.head = self.get

            self.request = request
            self.args = args
            self.kwargs = kwargs

            # And continue as usual
            return self.dispatch(request, *args, **kwargs)

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())

        # We need to set these on the view function, so that breadcrumb
        # generation can pick out these bits of information from a
        # resolved URL.
        view.cls = cls
        view.initkwargs = initkwargs
        view.suffix = initkwargs.get(‘suffix‘, None)
        view.actions = actions
        return csrf_exempt(view)

    def initialize_request(self, request, *args, **kwargs):
        """
        Set the `.action` attribute on the view,
        depending on the request method.
        """
        request = super(ViewSetMixin, self).initialize_request(request, *args, **kwargs)
        method = request.method.lower()
        if method == ‘options‘:
            # This is a special case as we always provide handling for the
            # options method in the base `View` class.
            # Unlike the other explicitly defined actions, ‘metadata‘ is implicit.
            self.action = ‘metadata‘
        else:
            self.action = self.action_map.get(method)
        return request

    def reverse_action(self, url_name, *args, **kwargs):
        """
        Reverse the action for the given `url_name`.
        """
        url_name = ‘%s-%s‘ % (self.basename, url_name)
        kwargs.setdefault(‘request‘, self.request)

        return reverse(url_name, *args, **kwargs)

第四类 ModelViewSet 继承了这个类,ModelViewSet继承了四个混入类和一个泛类,

将会获得增删改查的所有方法。

class IndexView(ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = UserInfoSerializer


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

使用类视图的好处:
1、我们将各个HTTP请求方法之间,做了更好的分离。
2、可以很容易地,组成可重复使用的行为。

原文地址:https://www.cnblogs.com/presleyren/p/10706003.html

时间: 2024-10-11 04:29:56

Django rest framework (视图类详解)的相关文章

Django Rest Framework(2)-----序列化详解(serializers)

REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSerializer类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式. Serializers 序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染成JSON,XML或其他内容类型的原生Python类型.序列化器还提供反序列化,在验证传入的数据之后允许解析数据转换回复杂类型.不仅

Django之HttpServer服务器分析详解

大家知道,软件的正向工程,是从软件的需求获取开始,大概经历需求分析,概要分析,领域分析,设计分析,详细设计,代码实现,部署,实施这几个步骤,最终交付给用户使用.而在某些时候,比如某个软件产品是用PHP开发的,因为某些原因,我们想移植到JAVA平台去.或者某公司看到某个软件的市场前景很好,想COPY它的主要功能,然后经过加工润色后推出一个具有相同功能,更好用户体验或更多功能的软件.或者单纯的以研究软件的结构.设计思想为目的.基于这些需求,我们需要逆向工程.正向工程是一个从过程导出结果的步骤,而逆向

QAction类详解:

先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action that can be inserted into widgets. In applications many common commands can be invoked via menus, toolbar buttons, and keyboard shortcuts. Since the user

Android技术18:Android中Adapter类详解

1.Adapter设计模式 Android中adapter接口有很多种实现,例如,ArrayAdapter,BaseAdapter,CursorAdapter,SimpleAdapter,SimpleCursorAdapter等,他们分别对应不同的数据源.例如,ArrayAdater对应List和数组数据源,而CursorAdapter对应Cursor对象(一般从数据库中获取的记录集).这些Adapter都需要getView方法返回当前列表项显示的View对象.当Model发生改变时,会调用Ba

SpringMVC视图机制详解[附带源码分析]

目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html 本文将分析SpringMVC的视图这部分内容,让读者了解SpringMVC视图的设计原理. 重要接口和类介绍 1. View接口 视图基础接口,它的各种实现类是无

ThinkPHP视图查询详解

ThinkPHP视图查询详解 参考http://www.jb51.net/article/51674.htm 这篇文章主要介绍了ThinkPHP视图查询,需要的朋友可以参考下 ThinkPHP提供的视图查询应用功能十分强大,用户利用视图查询功能可以将多个数据表的字段内容按需要进行指定和筛选,组织成一个基于这些数据表的视图模型,然后就可以通过该模型直接进行多表联合查询,非常方便和简单. 例如在项目中,我们定义有三个表: user          用户基础表,user_info   用户详细信息表

Django REST framework - 视图

目录 Django REST framework 视图GenericAPIView GenericAPIView 例子 属性 混入 具体视图类 自定义基类 Django REST framework 视图GenericAPIView GenericAPIView 这个类扩展了REST框架的APIView类,通过GenericAPIView与一个或多个mixin类组合而构建的 例子 在使用通用视图时,将覆盖原视图,并设置多个类属性 from django.contrib.auth.models i

Django REST framework视图

Django REST framework视图 学习序列化的时候发现有大量的冗余代码,所以我们要使用Django REST framework里的视图减少我们的代码 DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据. 在API

iOS开发——代码生成TabBar与视图切换详解

我在之前多篇博客中讲解了在不使用storyboard而使用nib文件的情况下,使用代码生成导航栏并进行跳转,具体可以参考<iOS开发--界面跳转与返回及视图类型详解><iOS纯代码实现界面建立.跳转.导航栏(无storyboard.无nib)(Objective-C)>.今天我来讲解下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转.代码示例已经上传至:https://github.com/chenyufeng1991/TabBarTest   . (1)