nor*_*tpy 71 python django serialization json django-rest-framework
使用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)
Run Code Online (Sandbox Code Playgroud)
并且给出了这个JSON请求:
{
"book_id":1,
"pages":[
{
"page_id":2,
"text":"loremipsum"
},
{
"page_id":4,
"text":"loremipsum"
}
]
}
Run Code Online (Sandbox Code Playgroud)
如何编写嵌套的序列化程序来处理此JSON,并为page给定的每个JSON book创建新页面或更新(如果存在).
class RequestSerializer(serializers.Serializer):
book_id = serializers.IntegerField()
page = PageSerializer(many=True)
class PageSerializer(serializers.ModelSerializer):
class Meta:
model = Page
Run Code Online (Sandbox Code Playgroud)
我知道用一个实例化序列化器instance会更新当前的序列化器,但我应该如何在create嵌套序列化器的方法中使用它?
Tom*_*tie 97
首先,您是要支持创建新书实例还是仅更新现有实例?
如果你只想创建新的书籍实例,你可以做这样的事情......
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
Run Code Online (Sandbox Code Playgroud)
请注意,我没有包括在book_id这里.当我们创建图书实例时,我们不会包含图书ID.当我们更新图书实例时,我们通常会将图书ID作为网址的一部分,而不是请求数据.
如果你想支持创建和书籍实例的更新,那么你需要考虑一下你要如何处理未包含在请求页面,但在当前与书实例相关联.
您可以选择静默忽略这些页面并保持原样,您可能希望引发验证错误,或者您可能希望删除它们.
假设您要删除请求中未包含的任何页面.
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
Run Code Online (Sandbox Code Playgroud)
您可能还希望仅支持书籍更新,而不支持创建,在这种情况下,仅包括update()方法.
还有各种方法可以减少查询次数,例如.使用批量创建/删除,但上面会以相当简单的方式完成工作.
正如您所看到的,在处理嵌套数据时您可能需要的行为类型存在微妙之处,因此请仔细考虑您在各种情况下期望的行为.
另请注意,我一直在使用Serializer上面的示例而不是ModelSerializer.在这种情况下,仅显式地包含序列化程序类中的所有字段更简单,而不是依赖于ModelSerializer默认生成的自动字段集.
| 归档时间: |
|
| 查看次数: |
26459 次 |
| 最近记录: |