当您编写序列化程序时,指定将包含哪些字段(通过Meta
的{{1}}),设置它们的读/写权限并验证它们是微不足道的。但是,我想知道是否有一种简单的方法来指定仅所包含的字段是预期的,并且传入的任何额外密钥都会引发错误。
E.g。说,我有一个序列化器
fields
进一步假设我没有任何验证。
我class ModelASerializer(serializers.ModelSerializer):
class Meta:
model = models.ModelA
fields = ('name', 'number')
这个有效负载创建一个新实例
POST
一切都很好。
但假设我的API已更改,现在我还存储了一个新字段{
"name": "test",
"number": 5
}
,但忘记更新我的序列化程序。客户端将发送看似
title
然而,序列化程序将忽略额外的键,而不是引发异常。
所以,我的问题是:有没有办法让序列化程序只期望{
"name": "test",
"number": 5,
"title": "Mr"
}
中指定的字段或 - 如果它不是fields
字段,指定为成员,如果不是这样,则引发错误?
答案 0 :(得分:2)
您可以通过覆盖序列化程序的is_valid()
方法来实现。在这里,我们将使用payload
和filter()
函数检查lambda
中的任何密钥是否不是序列化程序字段。
如果filter()
返回一些不在序列化程序字段中的字段,那么我们会引发ValidationError
。否则,我们调用super()
方法,然后它将执行正常的序列化验证。
from django.core.exceptions import ValidationError
class MySerializer(..):
def is_valid(self, raise_exception=False):
if hasattr(self, 'initial_data'):
payload_keys = self.initial_data.keys() # all the payload keys
serializer_fields = self.fields.keys() # all the serializer fields
extra_fields = filter(lambda key: key not in serializer_fields , payload_keys)
if extra_fields:
raise ValidationError('Extra fields %s in payload'%extra_fields)
return super(MySerializer, self).is_valid(raise_exception)