视图-Django REST框架
decorators.py views.py
基于类的视图
Django的基于类的视图是与旧式视图不同的一个受欢迎的区别。
— 雷诺特·范里斯
REST框架提供了一个APIView
类,哪个类是Django的子类View
班级,等级。
APIView
类与常规类不同。View
课程以下列方式进行:
- 传递给处理程序方法的请求将是REST框架的
Request
实例,而不是Django的HttpRequest
实例。 - 处理程序方法可能返回REST框架的
Response
,而不是Django的HttpResponse
...视图将管理内容协商和在响应上设置正确的呈现器。 - 任何
APIException
例外情况将被捕获并调解成适当的反应。 - 传入的请求将进行身份验证,并在将请求发送给处理程序方法之前,将运行适当的权限和/或节流检查。
使用APIView
类与使用常规View
类,与往常一样,传入请求被分派到适当的处理程序方法,如.get()
或.post()
...此外,可以在控制API策略的各个方面的类上设置许多属性。
例如:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from django.contrib.auth.models import Userclass ListUsers(APIView):"""View to list all users in the system.* Requires token authentication.* Only admin users are able to access this view."""authentication_classes = [authentication.TokenAuthentication]permission_classes = [permissions.IsAdminUser]def get(self, request, format=None):"""Return a list of all users."""usernames = [user.username for user in User.objects.all()]return Response(usernames)
注*Django REST框架的全部方法、属性和关系APIView
, GenericAPIView
,各种Mixins
,和Viewsets
一开始很复杂。除了这里的文档之外,classy Django REST框架资源为Django REST Framework的基于类的每个视图提供了一个具有完整方法和属性的可浏览引用。
API策略属性
以下属性控制API视图的可插入方面。
.renderer类
解析器类
.身份验证类
.油门类
.权限类
内容协商类
API策略实例化方法
REST框架使用以下方法实例化各种可插入API策略。您通常不需要覆盖这些方法。
.Get_renderers(自)
.Get_分析器(Self)
.Get_验证器(自)
.Get_节流阀(自)
.Get_权限(自)
.Get_Content_Treator(Self)
.Get_Exception_处理程序(Self)
API策略实现方法
在将下列方法分派给处理程序方法之前,将调用以下方法。
检查权限(Self,Request)
.检查节流阀(自我,请求)
执行内容协商(Self,Request,force=false)
调度方法
视图直接调用下列方法.dispatch()
方法。它们执行在调用处理程序方法之前或之后需要执行的任何操作,如.get()
, .post()
, put()
, patch()
和.delete()
.
初始(Self,Request,args,*kwargs)
执行在调用处理程序方法之前需要执行的任何操作。此方法用于强制权限和节流,并执行内容协商。
您通常不需要重写此方法。
.Handle_Exception(Self,exc)
由处理程序方法引发的任何异常都将传递给此方法,该方法将返回Response
实例,或者重新引发异常。
默认实现处理rest_framework.exceptions.APIException
,以及Django的Http404
和PermissionDenied
异常,并返回适当的错误响应。
如果需要自定义API返回的错误响应,则应将该方法子类化。
初始化请求(Self,Request,args,*kwargs)
确保传递给处理程序方法的请求对象是Request
,而不是通常的DjangoHttpRequest
.
您通常不需要重写此方法。
完成响应(Self、Request、Response、args、*kwargs)
确保任何Response
从处理程序方法返回的对象将呈现为由内容协商确定的正确的内容类型。
您通常不需要重写此方法。
基于功能的视图
说[基于类的观点]总是更好的解决方案是错误的。
— 尼克·科夫兰
REST框架还允许您使用基于常规函数的视图。它提供了一组简单的装饰器,用于包装基于函数的视图,以确保它们接收到Request
(而不是通常的DjangoHttpRequest
)并允许它们返回Response
(而不是DjangoHttpResponse
),并允许您配置处理请求的方式。
@api_view()
签署: @api_view(http_method_names=['GET'])
此功能的核心是api_view
装饰器,它获取视图应该响应的HTTP方法列表。例如,您将编写一个非常简单的视图,只需手动返回一些数据:
from rest_framework.decorators import api_view@api_view()
def hello_world(request):return Response({"message": "Hello, world!"})
视图中指定的默认呈现器、解析器、身份验证类等。设置.
默认情况下仅限于GET
方法将被接受。其他方法将响应“405方法不允许”。若要更改此行为,请指定视图允许的方法,如下所示:
@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!"})
API策略装饰器
为了覆盖默认设置,REST框架提供了一组可以添加到视图中的附加装饰器。这些必须来后(以下)@api_view
装饰师。例如,若要创建使用节流阀若要确保特定用户每天只能调用一次,请使用@throttle_classes
装饰师,传递油门类列表:
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottleclass OncePerDayUserThrottle(UserRateThrottle):rate = '1/day'@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):return Response({"message": "Hello for today! See you tomorrow!"})
这些装饰器对应于设置为APIView
子类,如上所述。
现有的装饰师是:
@renderer_classes(...)
@parser_classes(...)
@authentication_classes(...)
@throttle_classes(...)
@permission_classes(...)
这些装饰器中的每一个都有一个参数,必须是一个类的列表或元组。
视图模式修饰器
若要重写基于函数的视图的默认架构生成,可以使用@schema
装饰师。一定要来后(以下)@api_view
装饰师。例如:
from rest_framework.decorators import api_view, schema
from rest_framework.schemas import AutoSchemaclass CustomAutoSchema(AutoSchema):def get_link(self, path, method, base_url):# override view introspection here...@api_view(['GET'])
@schema(CustomAutoSchema())
def view(request):return Response({"message": "Hello for today! See you tomorrow!"})
这个装潢师只拿了一个AutoSchema
实例,AutoSchema
子类实例或ManualSchema
实例,如模式文档...你可以通过None
以从架构生成中排除视图。
@api_view(['GET'])
@schema(None)
def view(request):return Response({"message": "Will not appear in schema!"})