Django Rest Framework:进一步理解序列化之基于类的视图
一,基于类的视图
REST framework 提供了一个 APIView 类,它是 Django 的 View 类的子类。基于类的视图必须继承APIView类。
- 传递给处理程序方法的请求将是 REST framework 的 Request 实例,而不是 Django 的 HttpRequest 实例。
- 处理程序方法可能会返回 REST framework 的 Response,而不是 Django 的 HttpResponse。该视图将管理内容协商并在响应中设置正确的渲染器。
- 任何 APIException 异常都会被捕获并调解为适当的响应。
- 传入的请求将被认证,并且在将请求分派给处理程序方法之前将运行适当的权限或限流检查。
Django Rest Framework:进一步理解序列化之基于函数的视图
二,使用基于类的视图
使用 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 User class ListUsers(APIView): """ 查看以列出系统中的所有用户。 * 需要令牌认证。 * 只有管理员用户才能访问此视图。 """ authentication_classes = (authentication.TokenAuthentication,) permission_classes = (permissions.IsAdminUser,) def get(self, request, format=None): """ 以列表格式返回所有用户。 """ usernames = [user.username for user in User.objects.all()] # 这是一个列表推导式 return Response(usernames)
1,重构为基于类的视图
from django.http import HttpResponse, JsonResponse, Http404 from snippet.models import Snippet from snippet.serializers import SnippetSerializer from rest_framework.response import Response from rest_framework import status from rest_framework.views import APIView class SnippetList(APIView): """ 列出所有的代码 snippet,或创建一个新的 snippet。 """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class SnippetDetail(APIView): """ 获取,更新或删除一个代码 snippet """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
- 必须继承APIView类。
- 具体序列化器的使用逻辑上与函数视图没什么区别,但对不同的 HTTP 方法有更好的分离。
2,重构路由
from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views urlpatterns = [ url(r'^snippet/$', views.SnippetList.as_view()), url(r'^snippet/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns)
- 与基于函数视图的url不同的是,基于类视图的url使用"序列化类名.as_view()方法"实现路由功能。
3,运行
结果与基于函数的视图一样。
三,通用视图
1,什么是通用视图
基于类的视图的一个关键好处是,它允许组合一些可重用行为。REST framework 利用这一点,通过提供许多预构建的视图即通用视图来提供常用模式,它们允许快速构建紧密映射到数据库模型的 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)
2,API 参考 (API Reference)
参考官方API Reference或 另一篇:Django Rest Framework:通用视图API Reference与视图集
四,使用mixins减少代码量
使用基于类的视图的优势之一是可以很容易撰写可重复使用的行为。
The create/retrieve/update/delete operations that we’ve been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework’s mixin classes.
到目前为止,我们一直在使用的create / retrieve / update / delete操作对于已经创建的任何模型支持的API视图非常相似。 这些常见行为在REST框架的mixin类中实现。
1,重构SnippetList
class SnippetList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)
- 使用 GenericAPIView 构建了视图,并且用上 ListModelMixin 和 CreateModelMixin提供核心功能,用 mixin类提供.list()和.create()操作。
- 将 get 和 post 方法绑定到适当的操作。
2,重构SnippetDetail
class SnippetDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
- 再次使用 GenericAPIView 类来提供核心功能,并添加 mixins 来提供 .retrieve(),.update() 和 .destroy() 操作。
3,运行
五,使用通用的基于类的视图进一步减少代码量
REST framework 提供了一套已经混合的通用视图。
from snippets.models import Snippet from snippets.serializers import SnippetSerializer from rest_framework import generics class SnippetList(generics.ListCreateAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer class SnippetDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer
- Django REST FrameWork中文教程3:基于类的视图
- Django REST framework教程三: 基于类的视图
- Django REST framework视图的用法
- Django基于类的视图(views)
- django 1.8 官方文档翻译: 3-4-1 基于类的视图
- django 1.8 官方文档翻译: 3-4-5 内建基于类的视图的API
- django之基于类的视图url映射
- Django Rest Framework的基础组件之视图:通用视图API Reference与视图集
- Django Rest Framework源码剖析(六)-----序列化(serializers)
- Django+jenkins+python+RESTful framework(基于Class的视图)(4) 转发邮件
- Django 1.6 基于类的通用视图
- 基于参数shared_pool_reserved_size进一步理解共享池shared pool原理
- Django 学习小组:基于类的通用视图详解(一)
- 对Django中通用视图generic的一些理解
- django 1.8 官方文档翻译: 3-4-3 使用基于类的视图处理表单
- Django中视图总结[urls匹配,HttpRequest对象,HttpResponse,render,redirect对象,对象序列化接受及案例]
- 基于 Django REST framework 3.6.2 文档的学习(1)—— 基本介绍
- django Rest Framework----序列化
- django Rest Framework----GenericAPIView 通用视图 GenericAPIView源码分析
- Django REST framework 中 3 种类视图的对比