基于类的视图 – Django Rest框架

基于类的视图 – Django Rest框架

基于类的视图有助于组成可重用的行为片段。Django REST框架提供了几个预建的视图,使我们能够重用常见的功能并保持我们的代码干燥。在本节中,我们将深入探讨Django REST框架中不同的基于类的视图。

APIView

APIView类提供了标准列表和细节视图的常用行为。通过APIView类,我们可以将根视图重写为基于类的视图。它们提供了诸如get()、post()、put()、patch()、delete()等动作方法,而不是定义处理方法。

使用APIView创建视图

让我们来看看如何使用APIView创建视图。views.py文件的模块如下。

from django.shortcuts import render
from django.http import Http404
  
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
  
from transformers.models import Transformer
from transformers.serializers import TransformerSerializer
  
class TransformerList(APIView):
    """
    List all Transformers, or create a new Transformer
    """
  
    def get(self, request, format=None):
        transformers = Transformer.objects.all()
        serializer = TransformerSerializer(transformers, many=True)
        return Response(serializer.data)
  
    def post(self, request, format=None):
        serializer = TransformerSerializer(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 TransformerDetail(APIView):
    """
    Retrieve, update or delete a transformer instance
    """
    def get_object(self, pk):
        # Returns an object instance that should 
        # be used for detail views.
        try:
            return Transformer.objects.get(pk=pk)
        except Transformer.DoesNotExist:
            raise Http404
  
    def get(self, request, pk, format=None):
        transformer = self.get_object(pk)
        serializer = TransformerSerializer(transformer)
        return Response(serializer.data)
  
    def put(self, request, pk, format=None):
        transformer = self.get_object(pk)
        serializer = TransformerSerializer(transformer, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  
    def patch(self, request, pk, format=None):
        transformer = self.get_object(pk)
        serializer = TransformerSerializer(transformer,
                                           data=request.data,
                                           partial=True)
        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):
        transformer = self.get_object(pk)
        transformer.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
Python

代码与普通的Django视图相似,但不同的HTTP方法之间有更好的分离。

  • get()方法处理HTTP GET请求
  • post()方法处理HTTP POST请求
  • put()方法处理HTTP PUT请求
  • patch()方法处理HTTP PATCH请求
  • delete()方法处理HTTP DELETE请求

设置URL配置

由于我们使用的是基于类的视图,我们在urls.py文件的路径中提到视图的方式略有不同。在app(transformers)文件夹中创建一个名为urls.py的新文件(如果不存在),并添加以下代码

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from transformers import views
  
urlpatterns = [
    path('transformers/', views.TransformerList.as_view()),
    path('transformers/<int:pk>/', views.TransformerDetail.as_view()),
]
  
urlpatterns = format_suffix_patterns(urlpatterns)
Python

接下来,设置根URL的配置。你可以打开urls.py(与settings.py文件所在的文件夹相同)并添加以下代码

from django.contrib import admin
from django.urls import path, include
  
urlpatterns = [
    path('', include('transformers.urls')),
]
Python

编写和发送HTTP请求

1.创建一个新条目 –

HTTPie的命令是。

http POST :8000/transformers/ name=”Optimus Prime” alternate_mode=”1979 Freightliner Semi” description=”Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader” alive=”True”

输出

HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 194
Content-Type: application/json
Date: Sat, 23 Jan 2021 03:48:46 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 Freightliner Semi",
    "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader",
    "id": 1,
    "name": "Optimus Prime"
}
Python

分享命令提示的截图供你参考。

基于类的视图 - Django Rest框架

2.检索一个现有条目

擎天柱的pk值是1。 让我们传递pk值并检索细节

HTTPie的命令是。

http GET :8000/transformers/1/

输出

HTTP/1.1 200 OK
Allow: GET, HEAD, OPTIONS
Content-Length: 194
Content-Type: application/json
Date: Sat, 23 Jan 2021 03:50:42 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 Freightliner Semi",
    "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader",
    "id": 1,
    "name": "Optimus Prime"
}
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

3.更新一个现有条目

让我们更新名为alive的字段,将其设置为False。HTTPie的命令是。

http PUT :8000/transformers/1/ name=”Optimus Prime” alternate_mode=”1979 Freightliner Semi” description=”Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader” alive=”False”

输出

HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length: 195
Content-Type: application/json
Date: Sat, 23 Jan 2021 04:22:30 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": false,
    "alternate_mode": "1979 Freightliner Semi",
    "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader",
    "id": 1,
    "name": "Optimus Prime"
}
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

4.部分更新现有条目

让我们部分地更新名为描述的字段。HTTPie的命令是。

http PATCH :8000/transformers/1/ description=”Optimus Prime is the strongest and most courageous and leader of all Autobots”

输出

HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length: 181
Content-Type: application/json
Date: Sat, 23 Jan 2021 04:32:40 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": false,
    "alternate_mode": "1979 Freightliner Semi",
    "description": "Optimus Prime is the strongest and most courageous and leader of all Autobots",
    "id": 1,
    "name": "Optimus Prime"
}
Python

分享命令提示的截图

基于类的视图 - Django Rest框架

5.删除一个现有条目

我们将创建一个新条目并删除它。让我们使用下面的HTTPie命令创建一个 “Test “条目。

http POST :8000/transformers/ name=”Test”

输出

HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 77
Content-Type: application/json
Date: Sat, 23 Jan 2021 04:34:41 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": false,
    "alternate_mode": null,
    "description": null,
    "id": 2,
    "name": "Test"
}
Python

现在让我们删除’Test’条目(pk=2)。删除条目的HTTPie命令是

http DELETE :8000/transformers/2/

输出

HTTP/1.1 204 No Content
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length: 0
Date: Sat, 23 Jan 2021 04:35:06 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Python

分享命令提示的截图

基于类的视图 - Django Rest框架

Mixins

混合器类允许我们组成可重用的行为片段。它们可以从rest_framework.mixins导入。让我们来讨论一下不同类型的混合器类

  • ListModelMixin : 它提供了一个.list(request, *args, kwargs)方法来列出一个queryset。如果查询集被填入,响应体有一个200 OK的响应,其中有查询集的序列化表示。
  • CreateModelMixin : 它提供了一个.create(request, *args, kwargs)方法来创建和保存一个新的模型实例。如果对象被创建,响应体有一个201 Created响应,其中有一个对象的序列化表示。如果无效,它会返回一个400 Bad Request的响应,其中有错误的细节。
  • RetrieveModelMixin : 它提供了一个.retrieve(request, *args, kwargs)方法用于在响应中返回一个现有的模型实例。如果一个对象可以被检索到,响应体有一个200 OK的响应,其中有一个对象的序列化表示。否则,它将返回一个404 Not Found
  • UpdateModelMixin : 它提供了一个.update(request, *args, kwargs)方法来更新和保存一个现有的模型实例。它还提供了一个.partial_update(request, *args, kwargs)方法,用于部分更新和现有的模型实例。.如果对象被更新,响应体有一个200 OK的响应,有一个对象的序列化表示。否则,400 Bad Request响应将被返回,并附有错误细节。
  • DestroyModelMixin : 它提供了一个.destroy(request, *args, kwargs)方法来删除一个现有的模型实例。如果一个对象被删除,响应体有一个204 No Content的响应,否则,它将返回一个404 Not Found

Note: We will be using GenericAPIView to build our views and adding in Mixins.

使用混合元素创建视图

让我们来看看我们如何利用Mixin类。views.py文件的模块如下。

from rest_framework import mixins
from rest_framework import generics
from transformers.models import Transformer
from transformers.serializers import TransformerSerializer
  
class TransformerList(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      generics.GenericAPIView):
    queryset = Transformer.objects.all()
    serializer_class = TransformerSerializer
  
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
  
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
  
class TransformerDetail(mixins.RetrieveModelMixin,
                        mixins.UpdateModelMixin,
                        mixins.DestroyModelMixin,
                        generics.GenericAPIView):
    queryset = Transformer.objects.all()
    serializer_class = TransformerSerializer
  
    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 patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)
  
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
Python

在这里,GenericAPIView类提供了核心功能,而我们正在向它添加混合类。querysetserializer_class是GenericAPIView类的基本属性。queryset属性用于从该视图返回对象,serializer_class属性用于验证、反序列化输入和序列化输出。

在TransformerList类中,我们使用了提供.list()和.create()动作的混合类,并将这些动作与get()和post()方法绑定。在TransformerDetail类中,我们使用了提供.retrieve()、.update()、.partial_update()和.destroy()动作的混合类,并将这些动作与get()、put()、patch()和delete()方法绑定。

构成和发送HTTP请求

1.创建一个新条目

HTTPie的命令是

http POST :8000/transformers/ name=”Bumblebee” alternate_mode=”1979 VW Beetle” description=”Small, eager, and brave, Bumblebee acts as a messenger, scout, and spy” alive=”True”

输出

HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 161
Content-Type: application/json
Date: Sat, 23 Jan 2021 04:58:26 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 VW Beetle",
    "description": "Small, eager, and brave, Bumblebee acts as a messenger, scout, and spy",
    "id": 3,
    "name": "Bumblebee"
}
Python

2.检索所有条目

HTTPie的命令是

http GET :8000/transformers/

输出

HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 345
Content-Type: application/json
Date: Sat, 23 Jan 2021 04:59:42 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

[
    {
        "alive": true,
        "alternate_mode": "1979 VW Beetle",
        "description": "Small, eager, and brave, Bumblebee acts as a messenger, scout, and spy",
        "id": 3,
        "name": "Bumblebee"
    },
    {
        "alive": false,
        "alternate_mode": "1979 Freightliner Semi",
        "description": "Optimus Prime is the strongest and most courageous and leader of all Autobots",
        "id": 1,
        "name": "Optimus Prime"
    }
]
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

基于类的通用视图

为了使用基于通用类的视图,视图类应该从rest_framework.generics.中导入。

  • CreateAPIView : 它提供了一个post方法处理程序,它被用于只创建的端点。CreateAPIView扩展了GenericAPIView和CreateModelMixin。
  • ListAPIView : 它提供了一个get方法处理程序,用于只读端点,代表模型实例的集合。ListAPIView扩展了GenericAPIView和ListModelMixin。
  • RetrieveAPIView : 它提供了一个获取方法处理程序,用于只读的终端,代表一个单一的模型实例。RetrieveAPIView扩展了GenericAPIView和RetrieveModelMixin。
  • DestroyAPIView : 它提供了一个删除方法处理程序,并用于单个模型实例的只删除端点。DestroyAPIView 扩展了 GenericAPIView 和 DestroyModelMixin。
  • UpdateAPIView : 它提供了put和patch方法的处理程序,用于单个模型实例的仅更新的端点。UpdateAPIView扩展了GenericAPIView和UpdateModelMixin。
  • ListCreateAPIView : 它提供了get和post方法的处理程序,用于读写端点,以表示模型实例的集合。ListCreateAPIView扩展了GenericAPIView、ListModelMixin和CreateModelMixin。
  • RetrieveUpdateAPIView : 它提供get、put和patch方法处理程序。它被用来读取或更新端点以表示一个单一的模型实例。RetrieveUpdateAPIView扩展了GenericAPIView、RetrieveModelMixin和UpdateModelMixin。
  • RetrieveDestroyAPIView : 它提供了获取和删除方法的处理程序,它被用于读取或删除端点,代表一个单一的模型实例。RetrieveDestroyAPIView扩展了GenericAPIView、RetrieveModelMixin和DestroyModelMixin。
  • RetrieveUpdateDestroyAPIView : 它提供get、put、patch和delete方法处理程序。它被用于读-写-删的端点,代表一个单一的模型实例。它扩展了GenericAPIView、RetrieveModelMixin、UpdateModelMixin和DestroyModelMixin。

使用基于类的通用视图创建视图

让我们看一下我们如何利用Mixin类。这里我们将利用ListCreateAPIView和RetrieveUpdateDestroyAPIView。views.py文件的模块如下。

from rest_framework import generics
  
from transformers.models import Transformer
from transformers.serializers import TransformerSerializer
  
class TransformerList(generics.ListCreateAPIView):
    queryset = Transformer.objects.all()
    serializer_class = TransformerSerializer
  
class TransformerDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Transformer.objects.all()
    serializer_class = TransformerSerializer
Python

你可以注意到,我们能够避免大量的模板代码。这些通用视图结合了来自混合类的可重用的行为片段。让我们看看ListCreateAPIView和RetrieveUpdateDestroyAPIView的声明。

class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        GenericAPIView):
   ......

class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                                   GenericAPIView):
  ......
Python

编写和发送HTTP请求

1.创建一个新条目

HTTPie的命令是

http POST :8000/transformers/ name=”Cliffjumper” alternate_mode=”1979 Porsche 924″ description=”His eagerness and daring have no equal” alive=”True”

输出

HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 133
Content-Type: application/json
Date: Sat, 23 Jan 2021 05:28:45 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 Porsche 924",
    "description": "His eagerness and daring have no equal",
    "id": 5,
    "name": "Cliffjumper"
}
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

2.更新一个现有条目

HTTPie的命令是

http PUT :8000/transformers/5/ name=”Cliffjumper” alternate_mode=”1979 Porsche 924″ description=”Eager and Daring” alive=”True”

输出

HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length: 111
Content-Type: application/json
Date: Sat, 23 Jan 2021 05:35:39 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 Porsche 924",
    "description": "Eager and Daring",
    "id": 5,
    "name": "Cliffjumper"
}
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

3.部分更新一个现有条目

http PATCH :8000/transformers/3/ alive=”True”

输出

HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length: 151
Content-Type: application/json
Date: Sat, 23 Jan 2021 05:37:54 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "alive": true,
    "alternate_mode": "1979 VW Beetle",
    "description": "Small, eager, and brave. Acts as a messenger, scout, and spy",
    "id": 3,
    "name": "Bumblebee"
}
Python

分享命令提示的截图供你参考

基于类的视图 - Django Rest框架

在本节中,我们探讨了Django REST框架提供的不同类型的基于类的视图。我们使用APIView实现了视图,并解释了不同类型的混合类。最后,我们揭示了各种类型的基于类的视图,并演示了它们如何避免大量的模板代码。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册