我使用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
答案 0 :(得分:0)
instance
是一个书籍列表,即要序列化的类的对象。 validated_data
是一个数据字典列表,其中每个item
类似于您传递的validated_data
,如果您使用的是非列表序列化程序。要访问图书对象的ID,您可以使用book.id
来访问validated_data
中商品的ID,您可以使用商品[' id']。
您需要一个非read_only id字段,因为如果您想要放置一个对象列表并替换整个集合,您需要传递ID以便定义一个项目是否应更新现有项目,如果是,则需要一个,或者如果一个项目是新的。这就是循环中发生的事情:在第一个循环中,项目要么被创建要么被更新,这取决于存在或不存在相同id的对象。在最后一个循环中,所有不在validated_data
中显示的项目都会被删除。
答案 1 :(得分:0)
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"
}
}