【问题标题】:Unable to understand the flow of list serializer update in django rest framework无法理解 django rest 框架中列表序列化程序更新的流程
【发布时间】:2017-10-18 15:28:39
【问题描述】:

我正在使用 list Serializer by many = True。 create 方法运行良好,但我无法理解 django rest 框架文档中列表序列化程序的自定义更新方法的流程。使用列表序列化程序的基础很清楚,但是当我在代码中使用它时,流程是无法理解的。我无法理解第四行中 book.items 的含义。什么是书?在文档中,它还要求向实例序列化程序添加显式 id 字段。默认隐式生成的 id 字段被标记为 read_only。希望了解文档在说什么以及如何实现它。文档中的上下文如下所示。

class BookListSerializer(serializers.ListSerializer):
def update(self, instance, validated_data):
    # Maps for id->instance and id->data item.
    book_mapping = {book.id: book for book in instance}
    data_mapping = {item['id']: item for item in validated_data}

    # Perform creations and updates.
    ret = []
    for book_id, data in data_mapping.items():
        book = book_mapping.get(book_id, None)
        if book is None:
            ret.append(self.child.create(data))
        else:
            ret.append(self.child.update(book, data))

    # Perform deletions.
    for book_id, book in book_mapping.items():
        if book_id not in data_mapping:a
            book.delete()

    return ret

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    instance 是书籍列表,即应序列化的类的对象。 validated_data 是一个数据字典列表,如果您使用非列表序列化程序,每个 item 类似于您传递的 validated_data。要访问书籍对象的 id,请使用 book.id,要访问 validated_data 中的项目 id,请使用 item['id']。 您需要一个非 read_only id 字段的原因,如果您想放置一个对象列表并替换整个集合,您需要传递 id 来定义,如果一个项目应该更新现有项目,如果是这样,哪个一个,或者如果一个项目是新的。这就是循环中发生的事情:在第一个循环中,创建或更新项目,取决于是否存在具有相同 id 的对象。在最后一个循环中,所有未出现在validated_data 中的项目都被删除。

    【讨论】:

      【解决方案2】:

      DRF 的文档有时有点过于“期望您了解 x 和 y 的来源”,而不是提供更清晰的示例。它可能有助于将改进的代码推送到您的代码库,但是,改进的代码在代码可读性方面并不总是更好(这也应该是开发人员技能的重要组成部分)。

      无论如何,我对您提供的代码也有同样的问题,经过一些修补后,我想通了。

          # Maps for id->instance and id->data item.
          book_mapping = {book.id: book for book in instance}
          data_mapping = {item['id']: item for item in validated_data}
      

      [x for x in y] 的架构称为list comprehension,它只是一种基于列表重新格式化列表或字典的方法。 由于在这些情况下,id 始终是唯一的,因此可以预期生成的 dict 具有唯一的键,这些键以书籍或项目作为其值。

      所以,即,如果实例是

      instance = [
        {
          "id": 2,
          "title": "hobbit",
          "author": "Megan"
        },
        {
          "id": 3,
          "title": "Milk",
          "author": "Eric"
        },
        ...
      ]
      

      那么图书映射的结果就是

      book_mapping = {book.id: book for book in instance}
      book_mapping = {
        "2": {
          "id": 2,
          "title": "hobbit",
          "author": "Megan"
        },
        "3": {
          "id": 3,
          "title": "Milk",
          "author": "Eric"
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-17
        • 1970-01-01
        • 2017-10-03
        • 2019-05-20
        • 2019-12-23
        • 2020-12-22
        • 2014-07-19
        相关资源
        最近更新 更多