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

使用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,并为page给定的每个序列号book创建一个新页面或更新(如果存在)。

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。在这种情况下,仅将所有字段显式包括在serializer类中,而不是依靠ModelSerializer默认情况下自动生成的字段集,会更简单。

以上是 django-rest-framework 3.0在嵌套序列化程序中创建或更新 的全部内容, 来源链接: utcz.com/qa/418687.html

回到顶部