rest framework Genericview

通用视图

Django的通用视图...被开发为普通使用模式的快捷方式......他们采取某些共同的习惯和模式的发展观和抽象,从而使您可以快速地将数据写入的共同看法,而不必重复自己发现的。

- Django文档

一个基于类的意见主要好处是它们允许你撰写的可重复使用的行为位的方式。REST架构充分利用了这通过提供一系列技术,可为常用的模式预先构建的意见。

通过REST框架提供的通用视图允许您快速建立密切映射到你的数据库模型API意见。

如果通用视图不适合你的API的需求,您可以下降到使用常规APIView类,或重新使用的通用视图来编写自己的一套可重用的通用视图的混入和基类。

例子

通常使用普通视图时,你会覆盖视图,并设置一些类属性。

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]

对于更复杂的情况下,您可能还希望覆盖视图类的各种方法。例如。

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)

对于非常简单的情况下,你可能想使用的任何类的属性通过.as_view()方法。例如,你的URLconf可能包括类似下面的条目:

url(r'^/users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list')

API参考

GenericAPIView

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

所提供的具体的通用视图分别由建相结合GenericAPIView,与一个或多个混入类。

属性

基本设置

下面的属性控制的基本看法行为。

  • 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的查找。

filter_queryset(self, queryset)

给定一个查询集,以取其过滤器后端都在使用它进行过滤,返回一个新的查询集。

例如:

def filter_queryset(self, queryset):
    filter_backends = [CategoryFilter]

    if 'geo_route' in self.request.query_params:
        filter_backends = [GeoRouteFilter, CategoryFilter]
    elif 'geo_point' in self.request.query_params:
        filter_backends = [GeoPointFilter, CategoryFilter]

    for backend in list(filter_backends):
        queryset = backend().filter_queryset(self.request, queryset, view=self)

    return queryset

get_serializer_class(self)

返回应当用于串行类。默认为返回的serializer_class属性。

可能会被改写,以提供动态行为,如使用不同的序列化器读取和写入操作,或提供不同的序列化到不同类型的用户。

例如:

def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer

保存和删除挂钩

通过混入类提供了以下的方法,并提供容易重写对象保存或删除行为的。

  • perform_create(self, serializer)-通过调用CreateModelMixin保存新的对象实例时。
  • perform_update(self, serializer)-通过调用UpdateModelMixin保存现有的对象实例时。
  • perform_destroy(self, instance)-通过调用DestroyModelMixin删除对象实例时。

这些钩子是用于设置在请求中隐含的属性是特别有用的,但不是请求数据的一部分。例如,你可能会基于请求用户在对象上设置一个属性,或基于URL关键字参数。

def perform_create(self, serializer):
    serializer.save(user=self.request.user)

这些覆盖点也是用于添加之前或保存的对象,诸如电子邮件的确认,或记录在更新后发生的行为是特别有用的。

def perform_update(self, serializer):
    instance = serializer.save()
    send_email_confirmation(user=self.request.user, modified=instance)

您也可以使用这些挂钩,以提供额外的验证,通过提高ValidationError()。如果你需要一些验证逻辑在数据库保存点申请这可能是有用的。例如:

def perform_create(self, serializer):
    queryset = SignupRequest.objects.filter(user=self.request.user)
    if queryset.exists():
        raise ValidationError('You have already signed up')
    serializer.save(user=self.request.user)

其他方法

你通常不会需要覆盖下面的方法,虽然你可能需要,如果你正在编写自定义视图使用调入它们GenericAPIView

  • get_serializer_context(self)-返回包含应提供给串行任何额外的上下文的字典。默认为包括'request''view''format'钥匙。
  • get_serializer(self, instance=None, data=None, many=False, partial=False) - 返回一个序列化实例。
  • get_paginated_response(self, data)-返回分页风格Response对象。
  • paginate_queryset(self, queryset)-一个分页查询集如果需要的话,无论是返回页面对象,或None如果分页未配置该视图。
  • filter_queryset(self, queryset) - 给定一个查询集,以取其过滤器后端都在使用它进行过滤,返回一个新的查询集。

混入

该混入类提供用于提供基本视图行为的行动。需要注意的是混入类提供的操作方法,而不是定义的处理方法,比如.get().post()直接。这使得行为更加灵活组成。

该混入类可以从进口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


具体视图类

下面是一些具体的通用视图。如果您使用通用视图这通常是你的,除非你需要高度定制的行为是工作的水平。

视图类可以从被导入rest_framework.generics

CreateAPIView

用于仅创建-端点。

提供了一种post方法处理。

扩展:GenericAPIViewCreateModelMixin

ListAPIView

用于只读端点代表模型实例的集合

提供了一种get方法处理。

扩展:GenericAPIViewListModelMixin

RetrieveAPIView

用于只读端点代表一个单一的模型实例

提供了一种get方法处理。

扩展:GenericAPIViewRetrieveModelMixin

DestroyAPIView

用于删除,只端点的单一模型实例

提供了一种delete方法处理。

扩展:GenericAPIViewDestroyModelMixin

UpdateAPIView

用于仅更新为端点单一模型实例

提供putpatch方法处理。

扩展:GenericAPIViewUpdateModelMixin

ListCreateAPIView

用于读写端点代表模型实例的集合

提供getpost方法处理。

扩展:GenericAPIViewListModelMixinCreateModelMixin

RetrieveUpdateAPIView

用于读取或更新端点代表一个单一的模型实例

提供getput并且patch方法处理。

扩展:GenericAPIViewRetrieveModelMixinUpdateModelMixin

RetrieveDestroyAPIView

用于读取或删除端点代表一个单一的模型实例

提供getdelete方法处理。

扩展:GenericAPIViewRetrieveModelMixinDestroyModelMixin

RetrieveUpdateDestroyAPIView

用于读写,删除端点代表一个单一的模型实例

提供getputpatchdelete方法处理。

扩展:GenericAPIViewRetrieveModelMixinUpdateModelMixinDestroyModelMixin


自定义通用视图

通常你会希望使用现有的一般看法,但使用一些轻微的定制行为。如果你发现自己重复使用在多个地方定制行为的某些位,则可能需要重构行为变成一个公共类,您可以根据需要那么就适用于任何视图或视图集。

创建自定义的混入

例如,如果你需要基于URL的conf多个字段来查找对象,你可以创建一个混合类像下面这样:

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

然后,您可以这样的mixin只是适用于您需要应用自定义行为视图或视图集随时随地。

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

使用自定义的混入是,如果你有自定义行为将要使用需要一个很好的选择。

创建自定义的基类

如果使用的是跨多个视图一个mixin,你可以借此更进一步,创建你自己的一套,然后可以在整个项目中使用的基本视图。例如:

class BaseRetrieveView(MultipleFieldLookupMixin,
                       generics.RetrieveAPIView):
    pass

class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
                                    generics.RetrieveUpdateDestroyAPIView):
    pass

使用自定义的基类是如果你有持续需要在大量的意见在整个项目中重复自定义行为一个不错的选择。


把尽可能创造

3.0版本之前,治疗的REST框架混入PUT作为任何更新或创建操作,取决于如果该对象已存在与否。

允许PUT作为创建操作是有问题的,因为它必然暴露有关的存在或对象不存在的信息。它也并不明显,它透明,允许之前删除的情况下重新建立一定比简单地返回一个更好的默认行为404的反应。

这两种风格“ PUT404”和“ PUT为打造”可以在不同的情况下有效,但是从3.0版本开始,我们现在使用404的行为默认的,因为它有更简单,更明显。

如果需要通用PUT,为创建行为,你可能要包括像这个AllowPUTAsCreateMixin的混入你的意见。


第三方软件包

下面的第三方软件包提供额外的通用视图实现。

Django的休息多模型

Django的休息多模型提供了用于经由单个API请求发送多个串行化模式和/或查询集的通用视图(以及混入)。

posted @ 2020-03-12 13:34  pythonliuwei  阅读(204)  评论(0编辑  收藏  举报