我正在使用Django 2.1,DRF 3.7.7。
我有一些模型及其相对的(模型)序列化器:这些模型是嵌套的,序列化器也是嵌套的。
让我举个例子:
# models.py
class City(models.Model):
name = models.CharField(max_length=50)
class Person(models.Model):
surname = models.CharField(max_length=30)
birth_place = models.ForeignKey(City)
# serializers.py
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = models.CitySerializer
fields = "__all__"
class PersonSerializer(serializers.ModelSerializer):
birth_place = CitySerializer()
class Meta:
model = models.Person
fields = "__all__"
如果我提交带有json之类的AJAX请求:
{'surname': 'smith', 'birth_place': 42}
我得到一个Bad Request
的回复,其中包含:Invalid data. Expected a dictionary, but got int.
如果我提交嵌套的json,例如:
{'surname': 'smith', 'birth_place': {'id': 42, 'name': 'Toronto'}}
关系未转换,id字段将被忽略,其余部分将解析为:
OrderedDict([('birth_place', OrderedDict([('name', 'Toronto')]))])
以下是我在基于类的视图上使用的post方法:
def post(self, request):
print("Original data:", request.data)
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
self.data = serializer.validated_data
print("Parsed data:", self.data)
...
我只需要从连接到序列化器的端点获取数据,我不需要通过REST接口写入/保存任何内容,因为表单的POST处理是由Django完成的
TL; DR :如何在不编写手工转换的情况下正确地向嵌套序列化器提交JSON请求?在设置序列化程序时是否犯了错误?
编辑:我发现,通过将id = serializers.IntegerField()
添加到序列化程序的父类(例如City),序列化程序解析器现在可以处理ID。至少现在我可以使用django在后端执行操作。
答案 0 :(得分:1)
django-rest的文档中没有明确地注明它。如果遵循序列化程序处理数据以进行创建的过程,那么很明显django通过先保存父实例然后添加m2m值来管理m2m,但是如果将m2m字段标记为只读。
解决方案是覆盖序列化程序的run_validation方法。序列化器应如下所示:
class ExampleSerializer(serializers.ModelSerializer):
queryset = SomeModel.objects.all()
tags = TagSerializer(many=True, read_only=True)
class Meta:
model = SomeModel
fields = ['pk', 'name', 'tags']
def run_validation(self, data):
validated_data = super(StudyResourceSerializer, self).run_validation(data)
validated_data['tags'] = data['tags']
return validated_data
请求正文应如下所示:
{
"tags": [51, 54],
"name": "inheritance is a mess"
}