【问题标题】:DjangoRestFramework ChoiceField fails float value validationDjangoRestFramework ChoiceField 浮点值验证失败
【发布时间】:2019-02-05 11:50:37
【问题描述】:

我对@9​​87654321@ 的验证逻辑有疑问。正如我在代码中看到的,这是用于验证客户端输入的ChoiceField 中的to_internal_value()

def to_internal_value(self, data):
    if data == '' and self.allow_blank:
        return ''

    try:
        return self.choice_strings_to_values[six.text_type(data)]
    except KeyError:
        self.fail('invalid_choice', input=data)

这是我对 Django 模型的声明:

class MyModel(BaseModel, ScopedModelMixin):
    my_field = models.FloatField(choices=MY_FLOAT_CHOICES, default=MY_FLOAT_CHOICES.default_value)

这是我来自django-model-utils==2.6.1 的选择对象声明:

from model_utils import Choices

MY_FLOAT_CHOICES = Choices(
    (1.0, 'choice1', 'Choice1'),
    (1.5, 'default_value', 'Choice2'),
    (2.0, 'choice3', 'Choice3')
)

因此,模型序列化程序中生成的字段是serializers.ChoiceField,在先前声明的模型级别提供了选项。

在验证来自客户端的用户输入时,DRF 无法正确验证浮点值。例如,当我发送:

{
    "myField": 1
}

它抛出"\"1\" is not a valid choice."。所以当我带着调试器来的时候就行了

return self.choice_strings_to_values[six.text_type(data)] 来自之前显示的 to_internal()ChoiceField,我看到它确实试图在选择列表中找到 '1'。当我更新我的选择时:

MY_FLOAT_CHOICES = Choices(
    (1, 'choice1', 'Choice1'),
    (1.5, 'default_value', 'Choice2'),
    (2, 'choice3', 'Choice3')
)

它并没有失败,但是我在发送1.0 而不是从1 发送时遇到了同样的问题,并且它不断循环。我应该在 DRF 存储库上提出问题,还是有更好的选择?

【问题讨论】:

    标签: django python-3.x django-rest-framework choicefield django-model-utils


    【解决方案1】:

    我猜你必须将 int 键转换为浮点数,这样它才能在选择元组中找到它。

    def to_internal_value(self, data):
        if data == '' and self.allow_blank:
            return ''
    
        try:
            key = six.text_type(float(data))
            return self.choice_strings_to_values[key]
        except (ValueError, KeyError) as e:
            self.fail('invalid_choice', input=data)
    

    【讨论】:

    • 这是 Rest Framework 代码,我无法更改,也不想创建自己的 ChoiceField 来覆盖此方法。然后由于选择的类型不同(检查模型字段的类型等......这似乎太复杂了),我将不得不实现更复杂的逻辑。
    猜你喜欢
    • 2014-03-31
    • 2014-04-18
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 2020-07-22
    • 2020-03-16
    相关资源
    最近更新 更多