rest_framework

请求request方法

请求解析

.data

request.data 返回请求的的正文的解析内容,类似于标准reques.POST 和request.FILES

  • 它包括所有已解析的内容,包括文件和非文件的输入
  • 它支持解析除以外的http方法的内容,可以获取PUT 和PACTH 请求的内容
  • 可以处理传入的表单数据, 也可以处理传入的json数据

.query_params

  • 相当于request.GET

.parsers

认证方式

  • 对API的不同部分使用不同的身份验证策略
  • 支持使用多种身份验证策略
  • 提供与传入请求关联的用户和令牌信息

与用户相关

.user

request.user 通常返回实例,django.contrib.auth.models.User ,如果身份未经验证,则返回django.contrib.auth.models.AnonymousUser

.auth

返回任何其他身份验证上下文,如果改请求未认证,返回None

.authenticators

在视图里面使用authentication_classes,或者在settings文件里面使用DEFAULT_AUTHENTICATORS

响应 responses

Response()

  • from rest_framework.response import Response
  • Response(data, status=None, template_name=None, headers=None, content_type=None)
  • Response 无法处理实例类,因此需要在创建Response 对象之前将数据序列化为原始数据类型
  • 可以使用REST框架的 Serializer类来进行数据序列化
    参数:
  • data:响应的序列化数据
  • status:响应的状态吗
  • template_name:使用了HTMLRenderer或其使用他自定义模板渲染器时才需要
  • headers :在响应中使用的HTTP标头字典
  • content_type:响应的内容类型

HttpResponse属性

你可以在响应中设置标头如:

response = Response()
response['Cache-Control'] = 'no-cache'

基于类的视图View

APIview

  • from rest_framework.views import APIView
  • 基础了Django 的View类,但也与View有所不同
  • 传递给除了程序方法的请求将是REST框架的Request实例,而不是django的HttpRequest 实例
  • 处理程序方法可能返回REST框架的Response而不是Django的HttpResponse。该视图将管理内容协商并在响应上设置正确的渲染器。
  • 任何APIException异常都将被捕获并调解为适当的响应。
  • 在将请求分派到处理程序方法之前,将对传入的请求进行身份验证并进行适当的权限和/或限制检查。
    例如:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from django.contrib.auth.models import User

class 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)

通用视图 Generic views

它的主要优点之一是它们允许你组成一些可重用行为的方式,

例子

通常,在使用通用视图时,你要写这几个属性

  • queryset
  • serializer_class
  • permission_classes
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser

class UserList(generics.ListCreateAPIView):
  queryset = User.objects.all()
  serializer_class = UserSerializer
  permission_classes = [IsAdminUser]

对于复杂情况,你还可以覆盖视图类里面的方法
generics.ListCreateAPIView 可以覆盖list 方法

class UserList(generics.ListCreateAPIView):
   queryset = User.objects.all()
   serializer_class = UserSerializer
   permission_classes = [IsAdminUser]

   def list(self, request):
       # Note the use of `get_queryset()` instead of `self.queryset`
       queryset = self.get_queryset()
       serializer = UserSerializer(queryset, many=True)
       return Response(serializer.data)

GenericAPIView

  • 该类扩展了REST框架的APIView类,为标准列表和详细信息视图添加了通常需要的行为。

  • 提供的每个具体的通用视图都是通过将GenericAPIView,和一个或多个mixin类组
    合而构建的。

属性

  • queryset-应该用于从该视图返回对象的查询集。通常,您必须设置此属性或重写get_queryset()方法。如果要覆盖视图方法,则必须进行调用get_queryset()而不是直接访问此属性,这queryset将被评估一次,并且这些结果将被缓存用于所有后续请求,这一点很重要。
  • serializer_class-应该用于验证和反序列化输入以及序列化输出的序列化器类。通常,您必须设置此属性或重写get_serializer_class()方法。
  • lookup_field-应该用于执行单个模型实例的对象查找的模型字段。默认为’pk’。请注意,使用超链接的API时,您需要确保双方的API意见和串行类设置查找字段,如果你需要使用一个自定义值。
  • lookup_url_kwarg-用于对象查找的URL关键字参数。URL conf应包含与此值相对应的关键字参数。如果未设置,则默认使用与相同的值lookup_field。

分页:

与列表视图一起使用时,以下属性用于控制分页。

  • pagination_class-对列表进行分页时应使用的分页类。默认值为与DEFAULT_PAGINATION_CLASS设置相同的值’rest_framework.pagination.PageNumberPagination’。设置pagination_class=None将禁用此视图上的分页。
    筛选:

  • filter_backends-应该用于过滤查询集的过滤器后端类的列表。默认值为与DEFAULT_FILTER_BACKENDS设置相同的值。

方法

基本方法:

get_queryset(self)

  • 返回应用于列表视图的查询集,该查询集应用作详细视图中的查询的基础。默认情况下返回queryset属性指定的查询集。

  • 应始终使用此方法,而不是self.queryset直接访问此方法,因为它self.queryset只会被评估一次,并且那些结果将为所有后续请求缓存。

  • 可以重写以提供动态行为,例如返回特定于发出请求的用户的查询集。
    例如:

def get_queryset(self):
    user = self.request.user
    return user.accounts.all()

get_object(self)

  • 返回应用于详细信息视图的对象实例,默认使用lookup_field 参数过滤基本查询集,可以重写以提供更复杂的行为,例如基于多个URL kwarg的对象查找
    例如:
def get_object(self):
   queryset = self.get_queryset()
   filter = {}
   for field in self.multiple_lookup_fields:
       filter[field] = self.kwargs[field]

   obj = get_object_or_404(queryset, **filter)
   self.check_object_permissions(self.request, obj)
   return obj

请注意,如果您的API不包含任何对象级别的权限,则可以选择排除self.check_object_permissions,而只需从get_object_or_404查找中返回对象即可

mixin 类

mixin类可以从导入rest_framework.mixins

ListModelMixin

  • 提供一种.list(request, *args, **kwargs)方法,该方法实现列出查询集。

  • 如果填充了查询集,则返回一个200 OK响应,并将查询集的序列化表示形式作为响应的主体。可以可选地对响应数据进行分页。

CreateModelMixin

  • 提供一种.create(request, *args, **kwargs)方法,该方法实现创建和保存新模型实例。

  • 如果创建了对象,则返回一个201 Created响应,该对象的序列化表示作为响应的主体。如果表示形式包含名为的键url,则将Location使用该值填充响应的标头。

  • 如果提供的用于创建对象的请求数据无效,400 Bad Request则将返回响应,并将错误详细信息作为响应的正文。

RetrieveModelMixin

  • 提供一种.retrieve(request, *args, **kwargs)方法,该方法实现在响应中返回现有模型实例。

  • 如果可以检索到对象,则返回一个200 OK响应,该对象的序列化表示作为响应的主体。否则将返回404 Not Found。

UpdateModelMixin

  • 提供一种.update(request, *args, **kwargs)方法,该方法实现更新和保存现有模型实例。

  • 还提供了一种.partial_update(request, *args, **kwargs)方法,该方法与该update方法类似,但是用于更新的所有字段都是可选的。这样可以支持HTTP PATCH请求。

  • 如果对象被更新,它将返回一个200 OK响应,该对象的序列化表示作为响应的主体。

  • 如果提供的用于更新对象的请求数据无效,400 Bad Request则将返回响应,并将错误详细信息作为响应的主体

DestroyModelMixin

  • 提供一种.destroy(request, *args, **kwargs)方法,该方法实现删除现有模型实例。

  • 如果删除对象,则返回204 No Content响应,否则将返回404 Not Found。

自定义通用视图

例如,如果您需要基于URL conf中的多个字段查找对象,则可以创建如下的mixin类:

class MultipleFieldLookupMixin(object):
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            if self.kwargs[field]: # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        self.check_object_permissions(self.request, obj)
        return obj

然后,您可以在需要应用自定义行为的任​​何时间简单地将此混入应用于视图或视图集。

class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_fields = ['account', 'username']

具体的视图类

以下类是具体的通用视图。如果您使用的是通用视图,那么通常这就是您要使用的级别,除非需要大量的自定义行为。

可以从中导入视图类rest_framework.generics。

CreateAPIView

  • 用于仅创建端点。

  • 提供post方法处理程序。

扩展:GenericAPIView,CreateModelMixin

ListAPIView

  • 用于只读端点,表示模型实例的集合。

  • 提供get方法处理程序。

扩展:GenericAPIView,ListModelMixin

检索APIView

  • 用于只读端点,以表示单个模型实例。

  • 提供get方法处理程序。

扩展:GenericAPIView,RetrieveModelMixin

销毁APIView

  • 用于单个模型实例的仅删除端点。

  • 提供delete方法处理程序。

扩展:GenericAPIView,DestroyModelMixin

UpdateAPIView

  • 用于单个模型实例的仅更新端点。

  • 提供put和patch方法处理程序。

扩展:GenericAPIView,UpdateModelMixin

ListCreateAPIView

  • 用于读写端点,表示模型实例的集合。

  • 提供get和post方法处理程序。

扩展:GenericAPIView,ListModelMixin,CreateModelMixin

RetrieveUpdateAPIView

  • 用于读取或更新端点以表示单个模型实例。

  • 提供get,put并且patch方法处理。

扩展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin

RetrieveDestroyAPIView

  • 用于读取或删除端点,以表示单个模型实例。

  • 提供get和delete方法处理程序。

扩展:GenericAPIView,RetrieveModelMixin,DestroyModelMixin

RetrieveUpdateDestroyAPIView

  • 用于读写删除端点,以表示单个模型实例。

  • 提供get,put,patch和delete方法处理。

扩展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

视图集

ViewSets

  • ViewSet 类只是一种类型的基于类的视图,不提供任何方法的处理程序,例如.get() .post 而是提供操作,如.list() 和.create()

  • 使用方法,a的方法处理程序ViewSet仅在完成视图时绑定到相应的动作.as_view()。

  • 通常,您将向路由器集注册视图集,而不是在urlconf中的视图集中显式注册视图,而是自动为您确定urlconf

  • 让我们定义一个简单的视图集,可用于列出或检索系统中的所有用户。
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response

class UserViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing or retrieving users.
    """
    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = User.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

如果需要,可以将此视图集绑定到两个单独的视图中,如下所示:

user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})

通常,我们不这样做,而是向路由器注册视图集,并允许自动生成urlconf。

from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
urlpatterns = router.urls

您通常不希望编写自己的视图集,而是要使用提供默认行为集的现有基类。例如:

class UserViewSet(viewsets.ModelViewSet):
    """
    A viewset for viewing and editing user instances.
    """
    serializer_class = UserSerializer
    queryset = User.objects.all()
  • 使用类有两个主要优点View。

  • 重复的逻辑可以合并为一个类。在上面的示例中,我们只需要指定queryset一次,它将在多个视图中使用。

  • 通过使用路由器,我们不再需要自己处理URL conf。

  • 两者都需要权衡。使用常规视图和URL conf更加明确,并给您更多的控制权。如果您想快速启动并运行,或者当您使用大型API并希望在整个过程中实施一致的URL配置,则ViewSets很有帮助。

ViewSet操作

  • REST框架随附的默认路由器将为一组标准的创建/检索/更新/销毁样式操作提供路由,如下所示:
class UserViewSet(viewsets.ViewSet):
    """
    Example empty viewset demonstrating the standard
    actions that will be handled by a router class.

    If you're using format suffixes, make sure to also include
    the `format=None` keyword argument for each action.
    """

    def list(self, request):
        pass

    def create(self, request):
        pass

    def retrieve(self, request, pk=None):
        pass

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass

Routers

SimpleRouter

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls

该方法有两个强制性参数register()

  • prefix 用于这组路由URL前缀
  • viewset 视图集类
  • (可选)你还可以指定其他参数
  • basename 用于创建URL名称,如果未设置,则名称将基于queryset视图集的属性自动生成,如果视图集不包含queryset属性,则必须basename在注册视图集市进行设置
  • 上面的示例将生成以下URL模式:
  • 网址格式:^user/$ 名称:‘user-list’
  • 网址格式:^user/{pk}/$ 名称:‘user-detail’
  • 网址格式:^accounts/$ 名称:‘account-list’
  • 网址格式:^accounts/{pk}/$ 名称:‘account_detail’
注意:该basename 参数用于指定视图名称模式的初始部分,通常,你不需要指定basename参数,但如果你有一个定义了自定义get_queryset 方法的视图,则该视图可能没有属性集,如果尝试注册该视图集,则会看到类似的错误
'basename' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.

这意味着basename注册视图集时需要显式设置参数,因为无法从模型名称自动确定该参数。

include与路由器一起使用

  • .urls路由器实例上的属性只是URL模式的标准列表。关于如何包含这些URL,有很多不同的样式。

  • 例如,您可以追加router.urls到现有视图的列表中…

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)

urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
]

urlpatterns += router.urls

另外,你也可以使用diango的include功能例如

urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    url(r'^', include(router.urls)),
]
  • 您可以使用include应用程序名称空间:
urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    url(r'^api/', include((router.urls, 'app_name'))),
]
  • 或应用程序和实例名称空间:

urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    url(r'^api/', include((router.urls, 'app_name'), namespace='instance_name')),
]
注意:如果将命名空间与超链接的序列化程序一起使用,则还需要确保view_name序列化程序上的所有参数都能正确反映名称空间。在上面的示例中,您需要包括一个参数,例如view_name='app_name:user-detail’超链接到用户详细信息视图的序列化程序字段的参数 。
自动view_name生成使用的模式%(model_name)-detail。除非您的模型名称实际发生冲突,否则在使用超链接序列化程序时最好不要为 Django REST Framework视图命名。

Parsers 解析器

如何确定解析器

当request.data 被访问时,REST框架将检测Content-Type传入请求上的标头,并确定使用那个解析器来解析请求内容

注意:开发客户端应用时,切记要确保Content_Type 在HTTP请求中发送数据时设置头,如果你没有设置内容内心,则大多数客户端将默认使用"applixation/x-www-form-urlencoded",如果要使用jquery 和ajax() 方法发送json数据时,则应确保包括该ContentType:‘application/json’

设置解析器

  • 可以使用DEFAULT_PARSER_CLASSES 设置全局默认解析器,例如,以下设置将允许带有json内容的请求,而不是默认的json或表单数据
    REST_FRAMEWORK = {
    ‘DEFAULT_PARSER_CLASSES’:{
    ‘rest_framework.parsers.JSONParser’,
    }
    }
  • 你还可以使用APIView基于类的视图来设置用于单个视图或视图集的解析器
    在类使用parser_classes 属性
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    """
    A view that can accept POST requests with JSON content.
    """
    parser_classes = [JSONParser]
    def post(self, request, format=None):
        return Response({'received data': request.data})
        

JSONParser

  • 解析json请求内容
  • .media_type:application/json

FormParser

  • 解析HTML表单内容。
  • .media_type:application/x-www-form-urlencoded

MulitiPartParser

  • 解析多个HTML表单内容,支持文件上传
  • .media_type: multipart/form-data

FileUploadParser

  • 解析原始文件上传内容。该request.data属性将是一个字典,'file’其中包含包含上载文件的单个键。

  • 如果通过URL关键字参数FileUploadParser调用与with一起使用的视图filename,则该参数将用作文件名。

  • 如果在没有filenameURL关键字参数的情况下调用它,则客户端必须在Content-DispositionHTTP标头中设置文件名。例如Content-Disposition: attachment; filename=upload.jpg。

  • .media_type:/
    笔记:

  • 的FileUploadParser是与本地客户端的使用,可以将文件上传的原始数据请求。对于基于网络的上传,或与多上传支持本地客户端,您应该使用MultiPartParser来代替。

  • 由于该解析器的media_type任何内容类型相匹配,FileUploadParser一般应在API视图设置的唯一的解析器。

  • FileUploadParser尊重Django的标准FILE_UPLOAD_HANDLERS设置和request.upload_handlers属性。有关更多详细信息,
    用法示例:

# views.py
class FileUploadView(views.APIView):
    parser_classes = [FileUploadParser]

    def put(self, request, filename, format=None):
        file_obj = request.data['file']
        # ...
        # do some stuff with uploaded file
        # ...
        return Response(status=204)

# urls.py
urlpatterns = [
    # ...
    url(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view())
]

自定义解析器

  • 要实现自定义解析器,应重写BaseParser,设置.media_type属性并实现.parse(self, stream, media_type, parser_context)方法。

  • 该方法应返回将用于填充request.data属性的数据。

  • 传递给的参数.parse()是:stream

媒体类型
  • 可选的。如果提供,这是传入请求内容的媒体类型。

  • 根据请求的Content-Type:标头,它可能比渲染器的media_type属性更具体,并且可能包括媒体类型参数。例如"text/plain; charset=utf-8"。

parser_context
  • 可选的。如果提供,则此参数将是一个字典,其中包含解析请求内容可能需要的任何其他上下文。

  • 默认情况下,这将包括以下键:view,request,args,kwargs。

class PlainTextParser(BaseParser):
    """
    Plain text parser.
    """
    media_type = 'text/plain'

    def parse(self, stream, media_type=None, parser_context=None):
        """
        Simply return a string representing the body of the request.
        """
        return stream.read()

渲染器Renderers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值