DjangoRestFramework ChoiceField не проходит проверку значения с плавающей запятой - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть вопрос относительно логики проверки serializers.ChoiceField.Как я видел в коде, вот to_internal_value() из ChoiceField, который используется для проверки входных данных клиента:

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, или есть какой-то лучший вариант?

1 Ответ

0 голосов
/ 05 февраля 2019

Полагаю, вам нужно преобразовать ключ int во float, чтобы он мог найти его в кортеже выбора.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...