Django rest framework DRF序列化程序接受序列化程序字符域的int值,而不是为未匹配的值生成错误

Django rest framework DRF序列化程序接受序列化程序字符域的int值,而不是为未匹配的值生成错误,django-rest-framework,Django Rest Framework,Django的好人 我在探索DRF,制作了一个简单的CRUDAPI,一切都很顺利,正如预期的那样工作,这里没有什么特别之处 但是,当我试图测试DRF将如何处理POST请求中丢失或错误值的不同情况时,我得到了一些对我来说非常奇怪的东西 让我们以这个片段为例,介绍请求后数据的主体: { "title": "It doesn't matter", "description": "A short one because

Django的好人

我在探索DRF,制作了一个简单的CRUDAPI,一切都很顺利,正如预期的那样工作,这里没有什么特别之处

但是,当我试图测试DRF将如何处理POST请求中丢失或错误值的不同情况时,我得到了一些对我来说非常奇怪的东西

让我们以这个片段为例,介绍请求后数据的主体:

{
    "title": "It doesn't matter",
    "description": "A short one because life is fast",
    "body": "Test test test test"
}
如您所见,所有值都是字符串

因此,我将字符串值替换为int值,而不是96,这是肯定的,令人惊讶的是POST请求成功了


序列化程序自己将int值转换为字符串并接受了请求,它没有引发错误或任何事情,因此有没有一个合理的解释来解释为什么一开始就发生了,而不是针对意外值引发错误?

DRF是如何设计的:

def to_internal_value(self, data):
    # We're lenient with allowing basic numerics to be coerced into strings,
    # but other types should fail. Eg. unclear if booleans should represent as `true` or `True`,
    # and composites such as lists are likely user error.
    if isinstance(data, bool) or not isinstance(data, (str, int, float,)):
        self.fail('invalid')
    value = str(data)
    return value.strip() if self.trim_whitespace else value
这是CharField方法,如下所示:

情况是,在这个方向上——这不是问题;由于您有时希望将数值保存为文本,例如税务识别号TIN等,因此在此处严格执行可能弊大于利


IntegerField-没有此行为,它将对值是否为整数进行非常严格的检查。

是,CharField将尝试调用str。。在对象上,将其转换为字符串。@WillemVanOnsem等等,什么!serilizers的意义是什么?将数据转换为简单的Python对象,这样就可以将其作为JSON、XML、csv等进行传递@WillemVanOnsem是的,我知道,但我的观点是,它应该严格执行映射,尤其是在从JSON转换为数据类型时,不管怎样,奥帕尔钦斯基在下面很好地解释了这一行为谢谢你的回答,先生,现在一切都清楚了。但我认为这是一件奇怪的事情,我发现这可能会导致比它解决的问题更多的问题。因为如果我想将一些数字保存为字符串,我知道我必须转换,但默认情况下,这样做会使错误的输入被接受,而不是拒绝它,“你理解我的观点,对吗?”马哈茂达德尔说,“是的,完全理解你的观点。情况是这样的:如果您想要数字-您需要IntegerField,在这里它不是一个提供字符串的选项,实际上如果您使用字符串DRF将尝试从中生成int-如果它将失败-您将得到一个错误,请求将不会被处理;但是-这是DRF团队的设计决定,在CharField上以不同的方式进行设计,不知何故,我也能理解这一观点;在查菲尔德不允许数字变得棘手——因为这样的输入是什么:这座建筑建于1983年;作为一个简单的描述;我想说的是,边界在哪里?“1985年”无效,但“1985年是伟大的一年”有效吗?我个人的感觉和意见是他们做了一个好的决定。这里有很多不必要的数字,在本例中,您希望将其视为整数字段中的数字;我理解你的观点和背后的原因,但这又是一个rest框架,所以无论谁使用端点都会知道应该提供什么,所以如果我想要一个数字的str repr,他会发送'1985',而不是1985',但是出错了,仍然工作会非常糟糕。您提供的示例在任何情况下都是有效的,因为默认情况下它是一个str,由“”括起