如何在 Django REST Framework 中返回自定义 JSON
Django Rest framework 是一个用于在 Django 中构建 API 的工具包。它提供处理 Python 中 HTTP 请求和响应的功能。Django Rest framework 使用序列化器和 Response 类来返回自定义 JSON 数据。在本文中,我们将探讨在 Django REST Framework 中返回自定义 JSON 的不同方法,以及一些示例。
序列化器和 Response 类
Django Rest Framework(DRF) 使用序列化器将复杂的数据类型(例如 Django 模型)转换为 JSON、XML 或其他可以轻松呈现为 HTTP 响应的内容类型。要返回自定义 JSON,您可以创建一个序列化器类,并使用 DRF 中的 Response 类来创建自定义响应。
语法
序列化器
serializers.FieldType()
在这里,在序列化器类内部,我们使用所需的字段类型(例如,CharField、IntegerField 等)定义字段,并将它们分配给相应的字段名称。
Response 类
Response(data, status=status.HTTP_200_OK)
在这里,我们从 rest_framework.response 模块导入 Response 类,并从 rest_framework 导入 status 模块。我们通过将要作为响应返回的数据和所需的 HTTP 状态代码(例如 HTTP_200_OK)传递给 Response 类构造函数来创建响应对象。
示例
在下面的示例中,我们有一个名为 Book 的模型,其字段包括标题、作者和价格。我们定义了一个序列化器类 BookSerializer,它将 Book 模型字段映射到序列化器字段。在 BookView 类的 get 方法内部,我们使用示例图书数据创建序列化器实例。然后,我们验证序列化器数据并使用 serializer.data 检索序列化数据。最后,我们使用 Response 类和 HTTP 200 状态代码返回序列化数据。
from rest_framework import serializers, status from rest_framework.response import Response from rest_framework.views import APIView class BookSerializer(serializers.Serializer): title = serializers.CharField() author = serializers.CharField() price = serializers.DecimalField(max_digits=5, decimal_places=2) class BookView(APIView): def get(self, request): books_data = [ {'title': 'Book 1', 'author': 'Author 1', 'price': 9.99}, {'title': 'Book 2', 'author': 'Author 2', 'price': 14.99}, {'title': 'Book 3', 'author': 'Author 3', 'price': 19.99} ] serializer = BookSerializer(data=book_data) serializer.is_valid(raise_exception=True) response_data = serializer.data return Response(response_data, status=status.HTTP_200_OK)
输出
HTTP 200 OK Allow: GET, HEAD, OPTIONS Content-Type: application/json Vary: Accept [ { "title": "Book 1", "author": "Author 1", "price": "9.99" }, { "title": "Book 2", "author": "Author 2", "price": "14.99" }, { "title": "Book 3", "author": "Author 3", "price": "19.99" } ]
自定义响应格式
Django Rest Framework 提供了一种使用 **渲染器** 模块自定义响应格式的方法。默认情况下,DRF 使用 JSONRenderer 类以 JSON 格式呈现响应。但是,我们可以定义自定义渲染器来修改响应结构或添加其他信息。
示例
在下面的示例中,假设我们想在响应中添加元数据,例如图书的总数。我们可以通过创建自定义渲染器并覆盖 render 方法来实现这一点。为此,我们通过子类化 JSONRenderer 类创建一个自定义渲染器类 **CustomRenderer**。在 render 方法内部,我们通过添加表示图书总数的 count 字段和包含图书数据的 results 字段来修改数据。然后,我们调用父 render 方法以获取包含修改后的数据的 JSON 响应。
from rest_framework import renderers class CustomRenderer(renderers.JSONRenderer): def render(self, data, accepted_media_type=None, renderer_context=None): response_data = {'count': len(data), 'results': data} return super().render(response_data, accepted_media_type, renderer_context) class BookView(APIView): renderer_classes = [CustomRenderer] def get(self, request): books = ['Book 1', 'Book 2', 'Book 3'] return Response(books, status=status.HTTP_200_OK)
输出
{"count":3,"results":["Book 1","Book 2","Book 3"]}
使用响应装饰器
Django Rest Framework 提供装饰器来简化返回自定义响应的过程。**@api_view** 装饰器允许您使用 renderer_classes 参数指定所需的响应格式。
示例
在下面的示例中,我们定义了一个名为 books 的视图函数,并用 @api_view 装饰器修饰它,以指定它应该只处理 GET 请求。我们还使用 @renderer_classes 装饰器指定响应应该使用我们的自定义渲染器 CustomRenderer 进行呈现。在函数内部,我们返回图书列表作为响应。
from rest_framework.decorators import api_view, renderer_classes @api_view(['GET']) @renderer_classes([CustomRenderer]) def books(request): books = ['Book 1', 'Book 2', 'Book 3'] return Response(books, status=status.HTTP_200_OK)
输出
{"count":3,"results":["Book 1","Book 2","Book 3"]}
运行示例
要运行示例并查看输出,您需要设置一个安装了 Django REST Framework 的 Django 项目。以下是步骤
创建一个新的 Django 项目
$ django-admin startproject bookstore
在项目中创建一个新的 Django 应用
$ cd bookstore $ python manage.py startapp api
通过修改 settings.py 文件配置 Django 项目和应用。将以下行添加到 INSTALLED_APPS 和 REST_FRAMEWORK 部分
INSTALLED_APPS = [ ... 'rest_framework', 'api', ] REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'api.renderers.CustomRenderer', ] }
在 api 应用目录的 views.py 和 serializers.py 文件中定义如上例所示的视图和序列化器
更新项目目录中的 urls.py 文件以包含 API 端点
from django.urls import path from api.views import BookView urlpatterns = [ path('books/', BookView.as_view()), ]
运行开发服务器
$ python manage.py runserver
在浏览器中访问 URL books,您应该会看到包含图书列表的自定义 JSON 响应。
结论
在本文中,我们讨论了如何在 Django Rest Framework 中使用 Python Django 框架返回自定义 JSON。我们探讨了实现此目标的不同方法,包括使用序列化器和 Response 类、使用渲染器自定义响应格式以及使用装饰器进行响应自定义。通过使用上述方法,我们可以相应地转换和格式化 JSON 响应。