Django-15-DRF类视图

DRF支持基于函数的视图,当然也会支持基于类的视图。

一、基于类的视图实现

1.1 视图实现

APIView类在以下方面与常规类不同

  • 传递给处理程序方法的请求将是 REST 框架的实例,而不是 Django 的实例。

  • 处理程序方法可能会返回 REST 框架的 ,而不是 Django 的 。该视图将管理内容协商,并在响应上设置正确的响应器。

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

# 基于类的视图,需要继承 APIView
class UserList(APIView):
    @staticmethod
    def get(request):
        return Response("GET请求")

    @staticmethod
    def post(request):
        return Response("POST请求")

1.2 url的写法

path('user/', views.UserList.as_view()),

1.3 发起GET请求

Django-15-DRF类视图
image.png

1.4 发起POST请求

Django-15-DRF类视图
image.png

1.5 在类视图中可用的属性策略

1.5.1 权限检查

  • 在将请求分派给处理程序方法之前,将对传入请求进行身份验证,并运行适当的权限和/或限制检查

authentication_classes:是否经过了认证
permission_classes:是否具有某些权限

class UserList(generics.ListCreateAPIView):
    # 是否认证
    authentication_classes = [authentication.TokenAuthentication]
    # 是否有这个权限
    permission_classes = [permissions.IsAdminUser]

    queryset = User.objects.all()
    serializer_class = UserSerializer
Django-15-DRF类视图
image.png


还支持如下设置


permission_classes = [IsAuthenticated|ReadOnly]
# 注意:它支持 & (和)、 | (或)和 〜 (不是)。

1.5.2 渲染器renderer_classes

REST framework提供了一个响应类Response,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
REST framework提供了Renderer 渲染器,用来根据请求头中的Accept(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。
全局的renderer可以在**REST_FRAMEWORK**中进行设置。
也可以使用renderer_classes在基于类的视图中单独使用。

渲染器类 渲染类型 说明
JSONRenderer application/json 将返回数据渲染成 JSON 数据样式, 并且你可以使用 indent 媒体类型参数制定你的缩进方式, 例如 Accept: application/json; indent=4
TemplateHTMLRenderer text/html 使用 Django 模板数据返回时, 将返回 HTML 类型数据, 并与其他返回数据不一样的是, 使用此渲染器返回数据不需要序列化, 但是在你创建并返回 Response 实例对象时需要制定 template_name 关键字参数
StaticHTMLRenderer text/html
BrowsableAPIRenderer text/html 将数据呈现为 Browsable API 的 HTML
AdminRenderer text/html 该渲染器适用于 CRUD 样式的 WebAPI, 这些 API 也应提供用户友好的界面来管理数据
HTMLFormRenderer text/html 将序列化数据呈现为 HTML, 次渲染器的输出不包含封闭的  标签以及隐藏的 CSRF 输入或任何提交按钮
MultiPartRenderer multipart/form-data; boundary=BoUnDaRyStRiNg 该渲染器用于渲染 HTML 多部分表单数据, 它不适合用作响应渲染器, 而是用于使用 REST 框架的测试客户端和测试请求工厂创建测试请求

例如:指定浏览器API的html

class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    # 指定浏览器API的html
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)

    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

返回的是如下内容,可以被浏览器进行渲染的HTML

Django-15-DRF类视图
image.png


如果用浏览器访问呢,就是如下的形式

Django-15-DRF类视图
image.png


如果修改成renderer_classes = (AdminRenderer,)就会呈现出如下的展示列表

Django-15-DRF类视图
image.png

1.5.3 限流throttle_classes

全局的限流可以在**REST_FRAMEWORK**中进行设置。

REST_FRAMEWORK = {
    # 这里先流泪
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',


    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon''2/min',
        'user''10/min'
    }
}

也可以使用throttle_classes在基于类的视图中单独使用。
如上:如果你是匿名用户,当你的每分钟请求数量累计达到2次时,就会被限流。如果你是认证用户,你的每分钟请求数量达到10次时才会被限流。
自定义限流类,然后再类视图中使用

class ArticleListAnonRateThrottle(AnonRateThrottle):
    THROTTLE_RATES = {"anon""5/min"}


# 自定义限流类,应该写到独立的文件中去最合适,这里为演示,写到了视图中
class ArticleListUserRateThrottle(UserRateThrottle):
    THROTTLE_RATES = {"user""30/min"}


class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    throttle_classes = [ArticleListAnonRateThrottle, ArticleListUserRateThrottle]

    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

1.5.4 解析器类parser_classes

根据请求头 content-type 选择对应的解析器对请求体内容进行处理。
有application/json,x-www-form-urlencoded,form-data等格式
可以全局配置中配置默认的解析器类

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser'
        'rest_framework.parsers.FormParser'
        'rest_framework.parsers.MultiPartParser'
    ]
}

当然也可以在每个视图类中单独使用解析器类

class UserList(generics.ListCreateAPIView):
    parser_classes = [JSONParser, ]

    queryset = User.objects.all()
    serializer_class = UserSerializer

1.5.5 内容协商content_negotiation_class

同内容协商就是返回响应时返回什么格式的数据。
同样可以在全局配置中进行配置,也可以在类视图中使用。

1.6 类视图中的方法策略

以下的策略方法用在API的策略,通常不用重写它:

  • get_renderers(self): 获取渲染器方法

  • get_parsers(self): 获取解释器方法

  • get_authenticators(self): 或缺认证方法

  • get_throttles(self): 获取节流方法

  • get_permissions(self): 获取权限方法

  • get_content_negotiator(self): 获取内容协商方法

1.7 类视图中策略实施方法

下列方法之前被称为调度处理程序方法:

  • check_permissions(self, request): 检查权限

  • check_throttles(self, request): 检查节流

  • check_content_negotiation(self, request, force=False): 检查内容协商

,在执行对应的属性策略前执行,可以自己实现这些方法用于实现特定功能

1.8 调度方法

这些执行任何操作,需要发生之前或之后调用处理程序方法等.

  • initial(self, request, *args, **kwargs): 执行任何操作,需要发生在处理程序方法之前被调用。这个方法是用来执行权限和节流,并执行内容协商。

  • handle_exception(self, exc):抛出的任何异常处理程序方法将被传递给这个方法,而返回响应实例,或者re-raises异常。

  • initialize_request(self, request, *args, **kwargs):确保请求对象传递给处理程序方法是request的一个实例,而不是django的HttpRequest

  • finalize_response(self, request, response, *args, **kwargs):确保任何响应处理程序方法返回的对象将被呈现到正确的内容类型

二、使用 mixin

使用基于类的视图的一大好处是,它允许我们轻松地编写可重用的业务类。
我们写业务代码,一直都是再写增删改查,但是对于任何模型来说,都会最基本的增删改查。可以把这些增删改查做成通用行为。这些通用行为在 REST 框架的 mixin 类中实现。
让我们来看看如何使用 mixin 类来组合视图。

2.1 视图实现

如果想实现增删改查,只需要实现ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin等mixin即可

from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets, status, mixins, generics
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet

from news.models import News
from news.serializers import GroupSerializer, UserSerializer, NewsModelSerializer
class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

2.2 GET请求

Django-15-DRF类视图
image.png

2.3 POST请求

Django-15-DRF类视图
image.png

2.4 小总结

基类提供核心功能,mixin 类提供 and 操作。然后把指定的mixin实现绑定到具体的功能实现上。

三、使用基于类的泛型视图

使用 mixin 类,我们重写了视图,使用比以前略少的代码,但我们可以更进一步。
但是DRF提供了更加简单的泛型视图功能,可以再次减少一些代码的实现。
先说用法

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

以上就是最终代码,可以访问了。重点就在与generics.ListCreateAPIView。
继续研究代码的话,可以进入generics这个文件中去,可以看到如下方法

Django-15-DRF类视图
image.png


继续打开一个看具体类的方法

Django-15-DRF类视图
image.png


看到这里,就知道为什么基于类的泛型视图,这么强大了吧。


四、基于函数的视图

DRF框架还允许您使用基于常规函数的视图。它提供了一组简单的装饰器,用于包装基于函数的视图,以确保它们接收到是DRF的实例,并允许它们返回DRF的响应,并允许您配置请求的处理方式

4.1 @api_view()

功能的核心是装饰器,它采用视图应响应的 HTTP 方法列表。例如,您可以这样编写一个非常简单的视图,该视图仅手动返回一些数据:

from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view()
def hello_world(request):
    return Response({"message""Hello, world!"})

此视图将使用settings.py文件中REST_FRAMEWORK中指定的默认渲染器、解析器、身份验证类等。
默认情况下,仅接受方法。其他方法将响应“405 Method Not Allowed”。若要更改此行为,请指定视图允许的方法

@api_view(['GET', 'POST'])
def hello_world(request):
    if request.method == 'POST':
        return Response({"message""Got some data!""data": request.data})
    return Response({"message""Hello, world!"})

4.2 API 策略装饰器

为了覆盖默认设置,REST 框架提供了一组额外的装饰器,可以将其添加到视图中。这些必须位于装饰器之后(下方)。例如,若要创建使用限制的视图,以确保特定用户每天只能调用一次,请使用装饰器

from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottle

class OncePerDayUserThrottle(UserRateThrottle):
    rate = '1/day'

@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
    return Response({"message""Hello for today! See you tomorrow!"})

可用的装饰器有:

  • @renderer_classes(…)

  • @parser_classes(…)

  • @authentication_classes(…)

  • @throttle_classes(…)

  • @permission_classes(…)

这些装饰器中的每一个都接受一个参数,该参数必须是类的列表或元组。


原文始发于微信公众号(Python之家):Django-15-DRF类视图

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/198060.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!