我试图找到一个优雅的解决方案,以解决使用Django REST框架遇到的这个问题。我们有一个带有子对象和一对一关系的父模型。我们的要求是子对象是可选的,可以为null,也可以从先前存在的值修补为null。另外,如果父对象被删除,那么子对象也应该是这样。django rest框架嵌套对象
这种简单的设置,再现问题:
class ChildSerializer(serializers.ModelSerializer):
class Meta:
model = Child
class ParentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Parent
parent_value = serializers.CharField(required=False, max_length=1024)
child = ChildSerializer(read_only=False, required=False, many=False)
class Parent(models.Model):
class Meta:
app_label = "testparent"
parent_value = models.CharField(max_length=1024, null=True, blank=True)
class Child(models.Model):
class Meta:
app_label = "testparent"
child_value = models.CharField(max_length=1024, null=True, blank=True)
parent = models.ForeignKey(Parent, null=True, blank=True, related_name="child")
class ParentViewSet(viewsets.ModelViewSet):
permission_classes = (AllowAny,)
queryset = Parent.objects.all()
serializer_class = ParentSerializer
这工作:
{
"parent_value": "abc",
"child": { "child_value": "something" }
}
这得到一个错误:
{
"parent_value": "abc",
"child": null
}
注意,子对象是可选默认情况下,REST框架使用null填充字段。
我使用Django v.1.5.4和REST框架v.2.3.13
错误:
Traceback:
File "{site-packages}/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "{site-packages}/rest_framework/viewsets.py" in view
78. return self.dispatch(request, *args, **kwargs)
File "{site-packages}/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "{site-packages}/rest_framework/views.py" in dispatch
400. response = self.handle_exception(exc)
File "{site-packages}/rest_framework/views.py" in dispatch
397. response = handler(request, *args, **kwargs)
File "{site-packages}/rest_framework/mixins.py" in create
54. self.object = serializer.save(force_insert=True)
File "{site-packages}/rest_framework/serializers.py" in save
596. self.save_object(self.object, **kwargs)
File "{site-packages}/rest_framework/serializers.py" in save_object
1023. setattr(obj, accessor_name, related)
File "{site-packages}/django/db/models/fields/related.py" in __set__
474. manager.add(*value)
Exception Value: add() argument after * must be a sequence, not NoneType
我们目前正在使用的解决办法是有一个OneToOne领域然后使用post_delete信号处理程序删除子对象。这感觉很不方便。一般来说,我们遇到了一些试图操纵嵌套对象的问题,并想知道我们是否错了,或者在这种情况下,我们是否遇到过django或其他框架中的错误。
谢谢!
您是否尝试过使用[PK相关领域(http://www.django-rest-framework.org/api-guide/relations#primarykeyrelatedfield),而不是一个子串?我相信,根据你的模型,这将工作。 – AdelaN
我们最终不得不创建验证函数来防止null条件。我们的结论是,django rest框架的嵌套对象功能尚不成熟,并且存在一些用例,这些用例在代码中不能被处理。 – JamesHutchison