【问题标题】:Sort Django Rest Framework JSON Output对 Django Rest Framework JSON 输出进行排序
【发布时间】:2015-12-06 00:42:36
【问题描述】:

我一直在 Django 之上开发一个 Web 应用程序,并且我将 Django Rest Framework 用于我的 API。有一个名为 Events 的模型类,我在 DRF 中的 EventsSerializer 是一个非常常见的序列化器,没有任何特殊配置。它只是转储 EventManager 返回的数据。

Event 模型类中有一个字段“type”。 我现在返回的 json 是:

{
    events: [
      {object1},
      {object2},
      .....
    ]
}

,作为 DRF api 中转储并由 django 返回的任何内容。

出于某种原因,我需要返回按“类型”字段分类的事件对象。例如,我需要得到这个:

{
    events: [
        type1: [{object1}, {object2},...],
        type2: [{object3}, {object4}, ...],
        .......
    ]
}

我确实搜索了与此相关的任何内容,但找不到合适的解决方案。您对此有什么建议吗?

提前致谢

【问题讨论】:

  • 请为您的序列化程序、模型和视图发布代码。

标签: python json django rest django-rest-framework


【解决方案1】:

您可以使用 SerializerMethodField 并在那里提供自定义序列化逻辑:

class EventSerializer(serializers.Serializer):
    events = serializers.SerializerMethodField(source="get_events")

    def get_events(self, events):
        event_list = {}
        return [event_list[e.type].add({e}) if event.type in event_list else event_list[event.type] = [] for event in events]

【讨论】:

  • 假设我遵循这个建议,这确实很好,我必须创建一个单独的序列化程序,因为应该公开所有事件字段。但我需要避免进行额外的 API 调用,等事件序列化程序已经到位
  • 我没听懂你能说得更具体点吗?
  • @koslib 要减少数据库调用,请在查询集中使用.filter, select_related and prefetch_related
  • 我想你的意思是等效 api 视图集中的查询集,对吧?
  • @koslib 我的意思是 api 视图中的查询集
【解决方案2】:

我有一个类似于以下的模型:

class Book(models.Model):
    title = models.CharField(max_length=200)

class Author(models.Model):
    name = models.CharField(max_length=200)
    books = models.ManyToManyField(Book)

Author 生成的 JSON 如下所示:

{
  "name": "Sir Arthur C. Clarke",
  "books": [
    {
      "title": "Rendezvous with Rama",
    },
    {
      "title": "Childhood's End",
    }
  ]
}

在 JSON 中,希望书籍按标题排序。由于书籍是通过prefetch_relatedorder_by 添加到视图的查询集中的,因此没有任何效果(生成的SQL 没有连接到Books 表)。我想出的解决方案是覆盖get 方法。在我的get 方法版本中,我让超类生成Response,并在返回之前修改它的数据(Python dict),如下所示。

我不太担心性能有两个原因:

  1. 因为 prefetch_related 已经在 Python 中而不是在数据库中完成连接
  2. 就我而言,每个AuthorBooks 数量相对较少
class AuthorView(RetrieveUpdateAPIView):

    queryset = Author.objects.prefetch_related(
        'books',
    )
    serializer_class = AuthorSerializer

    def get(self, request, *args, **kwargs):
        response = super().get(request, *args, **kwargs)

        def key_func(book_json):
            return book_json.get('title', '')

        books = response.data.get('books', [])
        books = sorted(books, key=key_func)
        response.data['books'] = books

        return response

【讨论】:

    猜你喜欢
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 2010-10-27
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多