gpt4 book ai didi

python - django-rest-framework 3.0 在嵌套序列化程序中创建或更新

转载 作者:IT老高 更新时间:2023-10-28 12:43:34 27 4
gpt4 key购买 nike

使用 django-rest-framework 3.0 并拥有这些简单的模型:

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


class Page(models.Model):
book = models.ForeignKey(Books, related_name='related_book')
text = models.CharField(max_length=500)

鉴于此 JSON 请求:

{
"book_id":1,
"pages":[
{
"page_id":2,
"text":"loremipsum"
},
{
"page_id":4,
"text":"loremipsum"
}
]
}

如何编写嵌套序列化程序来处理此 JSON,并为给定 book 的每个 page 创建新页面或更新(如果存在)。

class RequestSerializer(serializers.Serializer):
book_id = serializers.IntegerField()
page = PageSerializer(many=True)


class PageSerializer(serializers.ModelSerializer):
class Meta:
model = Page

我知道用 instance 实例化序列化程序会更新当前序列化程序,但我应该如何在嵌套序列化程序的 create 方法中使用它?

最佳答案

首先,您是要支持创建新书实例,还是只更新现有实例?

如果您只想创建新的图书实例,您可以执行以下操作...

class PageSerializer(serializers.Serializer):
text = serializers.CharField(max_length=500)

class BookSerializer(serializers.Serializer):
page = PageSerializer(many=True)
title = serializers.CharField(max_length=50)

def create(self, validated_data):
# Create the book instance
book = Book.objects.create(title=validated_data['title'])

# Create or update each page instance
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=book)
page.save()

return book

请注意,我没有在此处包含 book_id。当我们创建书籍实例时,我们不会包含书籍 ID。当我们更新图书实例时,我们通常会将图书 ID 作为 URL 的一部分,而不是在请求数据中。

如果您希望同时支持图书实例的创建和更新,那么您需要考虑如何处理请求中未包含但当前与图书实例关联的页面.

您可以选择默默地忽略这些页面并保持原样,您可能想要引发验证错误,或者您可能想要删除它们。

假设您要删除请求中未包含的所有页面。

def create(self, validated_data):
# As before.
...

def update(self, instance, validated_data):
# Update the book instance
instance.title = validated_data['title']
instance.save()

# Delete any pages not included in the request
page_ids = [item['page_id'] for item in validated_data['pages']]
for page in instance.books:
if page.id not in page_ids:
page.delete()

# Create or update page instances that are in the request
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=instance)
page.save()

return instance

您也可能希望支持图书更新,而不支持创建,在这种情况下,包含 update()方法。

还有多种方法可以减少查询的数量,例如。使用批量创建/删除,但上面的方法会以相当简单的方式完成这项工作。

正如您所见,在处理嵌套数据时可能需要的行为类型存在细微差别,因此请仔细考虑您在各种情况下所期望的行为。

另外请注意,我在上面的示例中一直使用 Serializer 而不是 ModelSerializer。在这种情况下,将所有字段显式包含在序列化程序类中会更简单,而不是依赖于 ModelSerializer 默认生成的自动字段集。

关于python - django-rest-framework 3.0 在嵌套序列化程序中创建或更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27434593/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com