如何在 Django REST 框架中返回自定义 JSON

pythonjsonframework

Django Rest 框架是一个用于在 Django 中构建 API 的工具包。它提供了处理 Python 中的 HTTP 请求和响应的特性和功能。Django Rest 框架使用序列化器和响应类来返回自定义 JSON 数据。在本文中,我们将探讨在 Django REST 框架中返回自定义 JSON 的不同方法以及示例。

序列化器和响应类

Django Rest 框架 (DRF) 使用序列化器将复杂数据类型(例如 Django 模型)转换为 JSON、XML 或其他可以轻松呈现为 HTTP 响应的内容类型。要返回自定义 JSON,您可以创建一个序列化器类并使用 DRF 中的 Response 类创建自定义响应。

语法

  • 序列化器

serializers.FieldType()

在这里,在序列化器类中,我们使用所需的字段类型(例如 CharField、IntegerField 等)定义字段,并将它们分配给相应的字段名称。

  • 响应类

Response(data, status=status.HTTP_200_OK)

在这里,我们从rest_framework.response 模块和 rest_framework 中的 status 模块。我们通过将想要作为响应返回的数据和所需的 HTTP 状态代码(例如 HTTP_200_OK)传递给 Response 类构造函数来创建响应对象。

示例

在下面的示例中,我们有一个名为 Book 的模型,其中包含标题、作者和价格等字段。我们定义一个序列化器类 BookSerializer,将 Book 模型字段映射到序列化器字段。在 BookView 类的 get 方法中,我们使用示例书籍数据创建序列化器的实例。然后,我们验证序列化器数据并使用 serializer.data 检索序列化数据。最后,我们使用带有 HTTP 200 状态代码的 Response 类返回序列化数据。

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 提供了一种使用 renderers 模块自定义响应格式的方法。默认情况下,DRF 使用 JSONRenderer 类以 JSON 格式呈现响应。但是,我们可以定义自定义渲染器来修改响应结构或添加其他信息。

示例

在下面的示例中,假设我们想在响应中添加元数据,例如书籍总数。我们可以通过创建自定义渲染器并重写渲染方法来实现这一点。为此,我们通过子类化 JSONRenderer 类来创建自定义渲染器类 CustomRenderer。在渲染方法中,我们通过添加表示书籍总数的计数字段和包含书籍数据的结果字段来修改数据。然后,我们调用父渲染方法以获取具有修改后数据的 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 响应。

结论

在本文中,我们讨论了如何使用 Python Django 框架在 Django Rest Framework 中返回自定义 JSON。我们探索了实现此目标的不同方法,包括使用序列化程序和 Response 类、使用渲染器自定义响应格式以及利用装饰器进行响应自定义。通过使用上述方法,我们可以相应地转换和格式化 JSON 响应。


相关文章