【发布时间】:2016-01-13 16:19:56
【问题描述】:
根据 Django REST Framework 版本 3 documentation,为了创建可写的嵌套序列化程序,您需要编写自己的 create() 和 update() 方法。我的阅读和写作工作正常,但更新不起作用。
例如,如果我将以下数据发送到我的序列化程序 3 次,我最终会创建 3 个新的小部件。我预计传入一个预先存在的id 会触发更新并调用update(),但会调用create()。似乎id 被忽略了,因为它是自动生成的,所以这是有道理的,那么我该如何实现呢?
我感觉我遗漏了一些明显的东西,也许是我认为的一些额外处理?
views.py(目前真的很粗糙,请见谅)
from rest_framework.decorators import api_view
from rest_framework.response import Response
from widget.models import Widget
from widget.serializers import WidgetSerializer
@api_view()
def create(request):
data = {
"id": 4,
"widget_alpha": {
"bits": [
{
"id": 3,
"name": "bit 1",
"widget": 4
}
],
"bobs": [
{
"id": 3,
"name": "bob 1",
"widget": 4
}
],
"name": "my wid",
"widget": 4
},
"language": "en",
"code": "123"
}
serializer = WidgetSerializer(data=data)
if serializer.is_valid():
serializer.save()
else:
print serializer.errors
return Response({"message": "yay"})
Widget 是一个父模型,WidgetAlpha 是一个子模型,由几个 Bits 和 Bobs 组成。相关models.py 和serializers.py 代码如下。
models.py
from django.db import models
class Widget(models.Model):
LANGUAGE = (
('fr', 'French'),
('en', 'English'),
)
language = models.CharField(max_length=2, choices=LANGUAGE)
code = models.CharField(max_length=6)
class WidgetAlpha(models.Model):
widget = models.OneToOneField(Widget, primary_key=True, related_name='widget_alpha')
name = models.CharField(max_length=6)
class Bit(models.Model):
widget = models.ForeignKey(WidgetAlpha, related_name='bits')
name = models.CharField(max_length=6)
class Bob(models.Model):
widget = models.ForeignKey(WidgetAlpha, related_name='bobs')
name = models.CharField(max_length=6)
序列化器.py
from rest_framework import serializers
from widget.models import Widget, WidgetAlpha, Bit, Bob
class BitsSerializer(serializers.ModelSerializer):
class Meta:
model = Bit
class BobsSerializer(serializers.ModelSerializer):
class Meta:
model = Bob
class WidgetAlphaSerializer(serializers.ModelSerializer):
bits = BitsSerializer(many=True)
bobs = BobsSerializer(many=True)
class Meta:
model = WidgetAlpha
class WidgetSerializer(serializers.ModelSerializer):
widget_alpha = WidgetAlphaSerializer()
class Meta:
model = Widget
def create(self, validated_data):
widget_alpha_data = validated_data.pop('widget_alpha')
bits_data = widget_alpha_data.pop('bits')
bobs_data = widget_alpha_data.pop('bobs')
widget = Widget.objects.create(**validated_data)
alpha_widget = WidgetAlpha.objects.create(widget=widget, **widget_alpha_data)
for bit_data in bits_data:
Bit.objects.create(widget=alpha_widget, **bit_data)
for bob_data in bobs_data:
Bob.objects.create(widget=alpha_widget, **bob_data)
return widget
def update(self, instance, validated_data):
# never get here :(
return instance
【问题讨论】:
-
您也可以添加您的视图吗?
-
views.py 已添加
-
你不会在任何地方打电话给
update。如果你想调用更新,你需要创建类似这样的序列化器对象:serializer = WidgetSerializer(object, data=data) -
是的,看起来就是这个问题,需要传递一个实例。来自文档:“调用 .save() 将创建一个新实例或更新现有实例,具体取决于在实例化序列化程序类时是否传递了现有实例:”
-
那么,它奏效了吗?如果是这样,您可以将其发布为答案并接受吗?记得引用@DevilPinky 评论:)
标签: python django serialization django-rest-framework