我得到一个奇怪的结果,POST
JSON到DRF端点返回:
{"photos":["This field is required."],"tags":["This field is required."]}'
当POST
表单数据时,DRF并不介意字段为空。
我的模特是:
class Story(CommonInfo):
user = models.ForeignKey(User)
text = models.TextField(max_length=5000,blank=True)
feature = models.ForeignKey("Feature", blank=True, null=True)
tags = models.ManyToManyField("Tag")
我的序列化器是:
class StorySerializer(serializers.HyperlinkedModelSerializer):
user = serializers.CharField(read_only=True)
def get_fields(self, *args, **kwargs):
user = self.context['request'].user
fields = super(StorySerializer, self).get_fields(*args, **kwargs)
fields['feature'].queryset = fields['feature'].queryset.filter(user=user)
fields['photos'].child_relation.queryset = fields['photos'].child_relation.queryset.filter(user=user)
return fields
class Meta:
model = Story
fields = ('url', 'user', 'text', 'photos', 'feature', 'tags')
我的api.py
是:
class StoryViewSet(viewsets.ModelViewSet):
serializer_class = StorySerializer
def get_queryset(self):
return self.request.user.story_set.all()
def perform_create(self, serializer):
serializer.save(user=self.request.user)
结果:
# JSON request doesn't work
IN: requests.post("http://localhost:8001/api/stories/",
auth=("user", "password",),
data=json.dumps({'text': 'NEW ONE!'}),
headers={'Content-type': 'application/json'}
).content
OUT: '{"photos":["This field is required."],"tags":["This field is required."]}'
# Form data request does work
IN: requests.post("http://localhost:8001/api/stories/",
auth=("user", "password",),
data={'text': 'NEW ONE!'},
).content
OUT: '{"url":"http://localhost:8001/api/stories/277/","user":"user","text":"NEW ONE!","photos":[],"feature":null,"tags":[]}'
答案 0 :(得分:5)
这里的问题起初并不明显,但它与表单数据的缺点以及如何处理部分数据有关。
表单数据有两个Django REST框架必须处理的特殊情况
这两者结合在一起使得难以在Django REST框架中处理接受表单数据,因此它必须处理与大多数解析器不同的一些事情。
None
或字段的默认值。这是因为没有值的输入不会在表单数据中传递,因此缺少其键。但同样不适用于JSON。由于您没有为photos
和tags
密钥传递空列表,因此DRF不知道为默认值提供什么,并且不会将其传递给序列化程序。因此,序列化程序发现没有传入任何内容并触发验证错误,因为未提供必填字段。
因此解决方案是在使用JSON时不断提供所有密钥(不包括PATCH
请求,这可能是部分的),即使它们不包含任何数据。