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请求

1.4 发起POST请求

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

还支持如下设置
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

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

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

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请求

2.3 POST请求

2.4 小总结
基类提供核心功能,mixin 类提供 and 操作。然后把指定的mixin实现绑定到具体的功能实现上。
三、使用基于类的泛型视图
使用 mixin 类,我们重写了视图,使用比以前略少的代码,但我们可以更进一步。
但是DRF提供了更加简单的泛型视图功能,可以再次减少一些代码的实现。
先说用法
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
以上就是最终代码,可以访问了。重点就在与generics.ListCreateAPIView。
继续研究代码的话,可以进入generics这个文件中去,可以看到如下方法

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

看到这里,就知道为什么基于类的泛型视图,这么强大了吧。
四、基于函数的视图
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