Разрешение пустых дат с Зефиром - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь получить данные с веб-страницы. Эта страница содержит информацию о выпуске, но позволяет не устанавливать значения. Т.е. дата для тестирования из / в может быть пустой строкой.

Теперь я пытаюсь десериализовать все мои данные, высосанные со страницы, чтобы вставить их в базу данных и столкнуться с проблемами при обработке пустых дат.

from marshmallow import fields, Schema, ValidationError

class TestSchema(Schema):
    training_necessary = fields.Function(deserialize=lambda x: True if x == 'Yes' else False)
    test_from = fields.Date()
    test_to = fields.Date()

data = dict(training_necessary='Yes', test_from='', test_to='')

try:
    validated = TestSchema().load(data)
except ValidationError as err:
    print(f"{err}")

Результат:

{'test_to': ['Not a valid date.'], 'test_from': ['Not a valid date.']}

Я уже пробовал несколько комбинаций allow_none=True или default='', но ни одна из них не помогла моей пройти. Итак, как же можно разрешить пустые даты? Установка значения по умолчанию, подобного 1970-01-01, не поможет в этом случае.

Любые подсказки?

С уважением, Томас

+++ РЕДАКТИРОВАТЬ: РЕШЕНИЕ + ++ Вот рабочий код, который я получил после полезного совета Жерема:

from marshmallow import fields, Schema, ValidationError, pre_load

class TestSchema(Schema):
    training_necessary = fields.Function(deserialize=lambda x: True if x == 'Yes' else False)
    test_from = fields.Date(allow_none=True)
    test_to = fields.Date(allow_none=True)

    @pre_load(pass_many=False)
    def string_to_none(self, data, many, **kwargs):
        turn_to_none = lambda x: None if x == '' else x
        for k, v in data.items():
            data[k] = turn_to_none(v)
        return data

data = dict(training_necessary='Yes', test_from='', test_to='')

try:
    validated = TestSchema().load(data)
except ValidationError as err:
    print(f"{err}")

1 Ответ

1 голос
/ 02 марта 2020

Я бы вообще не передавал значения.

data = dict(training_necessary='Yes')

Или я бы сделал поля даты allow_none и передал бы None, а не пустую строку.

data = dict(training_necessary='Yes', test_from=None, test_to=None)

Если проблема в том, что ваш ввод содержит пустые строки, я бы сказал, что это проблема клиента, но вы можете добавить pre_load метод для удаления пустых строк из ввода перед десериализацией. Это более или менее эквивалентно изменению значений, которые вы счищаете со страницы перед передачей их в зефир.

...