通用视图

Django的通用视图......被开发为常见用法模式的快捷方式......它们采用视图开发中的某些常见习语和模式并对其进行抽象,以便您可以快速编写数据的常用视图,而无需重复自己。

- Django文档

基于类的视图的一个主要好处是它们允许您组合可重用行为的方式。REST框架通过提供许多预先构建的视图来提供常用模式来利用这一点。

REST框架提供的通用视图允许您快速构建与您的数据库模型紧密相关的API视图。

如果通用视图不适合您的API需求,您可以直接使用常规APIView类,或者重用通用视图使用的mixins和基类来组成您自己的可重用通用视图集。

例子

通常,在使用通用视图时,您将覆盖视图,并设置多个类属性。

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与一个或多个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查找中返回该对象。

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

保存和删除挂钩:

mixin类提供了以下方法,并提供了对象保存或删除行为的轻松覆盖。

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)

注意:这些方法取代旧式的2.x版pre_save,post_save,pre_delete和post_delete方法,这将不再可用。

其他方法:

您通常不需要覆盖以下方法,但如果您正在使用编写自定义视图,则可能需要调用它们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) - 给定一个查询集,使用正在使用的过滤后端进行过滤,返回一个新的查询集。

混入
mixin类提供用于提供基本视图行为的操作。请注意,mixin类提供了操作方法,而不是直接定义处理程序方法,例如.get()和.post()。这允许更灵活的行为组合。

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。

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

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

CreateAPIView
用于仅创建端点。

提供post方法处理程序。

扩展:GenericAPIView,CreateModelMixin

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

提供get方法处理程序。

扩展:GenericAPIView,ListModelMixin

RetrieveAPIView
用于表示单个模型实例的只读端点。

提供get方法处理程序。

扩展:GenericAPIView,RetrieveModelMixin

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

提供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

自定义通用视图
通常,您会希望使用现有的通用视图,但使用一些略微自定义的行为。如果您发现自己在多个位置重复使用某些自定义行为,则可能需要将该行为重构为公共类,然后可以根据需要将其应用于任何视图或视图集。

创建自定义mixins
例如,如果您需要根据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

然后,只要您需要应用自定义行为,就可以将此mixin简单地应用于视图或视图集。

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

如果您需要使用自定义行为,则使用自定义mixins是一个不错的选择。

创建自定义基类
如果您在多个视图中使用mixin,则可以更进一步,创建自己的一组基本视图,然后可以在整个项目中使用。例如:

class BaseRetrieveView(MultipleFieldLookupMixin,generics.RetrieveAPIView):
pass class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,generics.RetrieveUpdateDestroyAPIView):
pass

如果您的自定义行为始终需要在整个项目中的大量视图中重复,那么使用自定义基类是一个不错的选择。

PUT为创造
在3.0版之前,REST框架mixin被PUT视为更新或创建操作,具体取决于对象是否已存在。

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

两种样式“ PUTas 404”和“ PUTas create”在不同情况下都可以有效,但从版本3.0开始,我们现在使用404行为作为默认值,因为它更简单,更明显。

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

第三方包
以下第三方包提供了其他通用视图实现。

Django REST框架批量
在Django的REST的架构,散包实现通用视图混入以及一些普通混凝土通用视图允许通过API请求应用批量操作。

Django休息多个模型
Django Rest Multiple Models提供了一个通用视图(和mixin),用于通过单个API请求发送多个序列化模型和/或查询集。

Django-Rest framework中文翻译-generic-views的更多相关文章

  1. Django REST FrameWork中文教程2:请求和响应

    从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...

  2. Django REST framework 中文教程1:序列化

    建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...

  3. Django REST FrameWork中文教程3:基于类的视图

    我们也可以使用基于类的视图编写我们的API视图,而不是基于函数的视图.我们将看到这是一个强大的模式,允许我们重用常用功能,并帮助我们保持代码DRY. 使用基于类的视图重写我们的API 我们将首先将根视 ...

  4. Django-Rest framework中文翻译-Request

    REST framework的Request类扩展自标准的HttpRequest,增加了REST framework灵活的请求解析和请求验证支持. 请求解析 REST framework的Reques ...

  5. Django REST Framework API Guide 02

    本节大纲 1.Generic Views 2.ViewSets  1.Generic Views CBV的主要的一个优点就是极大的允许了对于代码的从用.自然,rest framework取其优势,提供 ...

  6. 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...

  7. 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...

  8. 《Django By Example》第九章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag 注:哈哈哈,第九章终于来啦 ...

  9. 《Django By Example》第十二章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第十二章,全书最后一章,终于到这章 ...

随机推荐

  1. 计算属性 computed

    计算属性 computed 计算缓存 vs Methods <div id="example"> <p>Original message: "{{ ...

  2. 基于Spark的GBDT + LR模型实现

    目录 基于Spark的GBDT + LR模型实现 数据预处理部分 GBDT模型部分(省略调参部分) GBDT与LR混合部分 基于Spark的GBDT + LR模型实现 测试数据来源http://arc ...

  3. 汇编程序49:实验14 访问CMOS RAM(显示系统时间)

    assume cs:code ;安装程序,使用指令out和in指令 code segment start: mov ax,cs mov ds,ax mov si,offset sub1 mov ax, ...

  4. C# 生成 bmp 格式的图片

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; usin ...

  5. ASP.NET 之页面重定向和传值

    在开发 ASP.NET 网站时,经常需要从一个网页重定向(导航)到另一个网页,同时希望能够将信息从源页传递到目标页.例如,如果你正在开发一个保险网站,需要用一个页面来收集基本信息(用户信息.保险产品信 ...

  6. 395 Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子串

    找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k .输出 T 的长度.示例 1:输入:s = "aaabb", k = 3输出:3最 ...

  7. java IO流 之 字节输入流 InputString()

    学习java的重点之一:InputStream  字节输入流的使用 (1)FileInputstream: 子类,读取数据的通道 使用步骤: 1.获取目标文件:new File() 2.建立通道:ne ...

  8. Python,报错NameError: name 'math' is not defined

    1 #-*- coding : utf-8 -*- 2 import math 3 4 def move(x, y, step, angle=0): 5 nx = x + step * math.co ...

  9. Elasticsearch--更好的搜索_加权得分,脚本,同义词

    目录 Apache Lucene评分 Elasticsearch的脚本功能 脚本执行过程中可以使用的对象 使用自定义的脚本库 搜索不同语言的内容 使用加权影响得分 加权 function_score查 ...

  10. moment.js 两个时间段的截取

    var a = moment([2008, 9, 29]);var b = moment([2007, 0, 10]);console.log(a.diff(b,'months'));//‘month ...