Django REST Framework:当 POST 上存在额外字段时引发错误
Posted
技术标签:
【中文标题】Django REST Framework:当 POST 上存在额外字段时引发错误【英文标题】:Django REST Framework: raise error when extra fields are present on POST 【发布时间】:2014-04-06 08:39:24 【问题描述】:在编写序列化程序时,指定将包含哪些字段(通过Meta
的fields
)、设置它们的读/写权限并验证它们是很简单的。但是,我想知道是否有一种简单的方法可以指定仅包含的字段是预期的,并且传入的任何额外键都应该引发错误。
例如比如说,我有一个序列化器
class ModelASerializer(serializers.ModelSerializer):
class Meta:
model = models.ModelA
fields = ('name', 'number')
进一步假设我没有任何验证。
我正在POST
ing 这个有效载荷来创建一个新实例
"name": "test",
"number": 5
一切都很好。
但假设我的 API 已更改,现在我还存储了一个新字段 title
,但忘记更新我的序列化程序。客户端将发送看起来像
"name": "test",
"number": 5,
"title": "Mr"
然而,序列化程序会简单地忽略额外的键,而不是引发异常。
所以,我的问题是:有没有办法让序列化程序仅期待fields
中指定的字段,或者——如果不是ModelSerializer
——字段,指定为成员,如果不是这种情况,则引发错误?
【问题讨论】:
你可以简单地覆盖restore_object
或restore_fields
,打电话给你的父母并检查提供的attrs
稍后再看这个问题,我可能会建议使用jsonschema
,如果有效负载未通过架构验证,则会出错。
这能回答你的问题吗? How to make a rest_framework Serializer disallow superfluous fields?
【参考方案1】:
遇到了这个问题,发现使用object level validation 更容易一些。这需要简单地定义一个验证方法:
class ModelASerializer(serializers.ModelSerializer):
...
def validate(self, data):
if hasattr(self, 'initial_data'):
unknown_keys = set(self.initial_data.keys()) - set(self.fields.keys())
if unknown_keys:
raise ValidationError("Got unknown fields: ".format(unknown_keys))
return data
【讨论】:
raise ValidationError(unknown_keys.pop(): 'Unexpected field')
也是一个选项。
从 djangorestframework==3.9.4 开始,这似乎不起作用
@SimonKohlmeyer 我不确定您的确切问题,但我遇到了上述检查的错误。所以我更新了答案以包括检查if hasattr(self, 'initial_data'):
,因为有时在设置self.initial_data
之前调用.validate
。
帮助很大。感谢您的回答。 @m【参考方案2】:
您可以通过覆盖序列化程序的is_valid()
方法来做到这一点。在这里,我们将使用filter()
和lambda
函数检查payload
中的任何键是否不是序列化器字段。
如果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)
【讨论】:
以上是关于Django REST Framework:当 POST 上存在额外字段时引发错误的主要内容,如果未能解决你的问题,请参考以下文章
Django REST Framework:当 POST 上存在额外字段时引发错误
python-django rest framework框架之路由