DRF Serializer устанавливает предоставленное поле в None - PullRequest
0 голосов
/ 27 января 2019

Я сейчас нахожусь в проекте, где я хочу проверить валидацию моих сериализаторов.Я сталкиваюсь с проблемой, что Serializer устанавливает предоставленное поле в None в процессе проверки, что не кажется мне разумным.

Здесь больше деталей (коротко для простоты):

models.py:

class Contract(models.Model):
    start_date = models.DateField()
    end_date = models.DateField()

serializers.py:

class ContractSerializer(serializers.ModelSerializer):

    class Meta:
        model = Contract
        fields = "__all__"

    def validate(self, attrs):
        """
        Object-level validation.
        Here we validate : start_date is, timewise, prior to end_date
        :param attrs:
        :return:
        """

        if not attrs["start_date"] < attrs["end_date"]:
            raise serializers.ValidationError("Sample Error Message.")

        return attrs

Я использую pytest для тестирования и pytest-django.

Мой conftest.py:

from pytz import datetime


@pytest.fixture
def valid_contract_json():
    start_date = datetime.date(2019, 1, 1)
    end_date = datetime.date(2019, 1, 31)

    data = {
        "start_date": start_date,
        "end_date": end_date,
    }

    return data

Мои тесты выглядят так:

test_serializers.py:

from app.serializers import ContractSerializer

class TestContractSerializer:
    def test_validation(self, valid_contract_json):
        ContractSerializer(data=valid_contract_json).is_valid(raise_exception=True)

При запуске этогоПроверьте, не удалось ли это, и покажите следующее сообщение:

TypeError: '<' не поддерживается между экземплярами 'datetime.date' и 'NoneType' </p>

Я провел некоторое исследованиена этом:

  1. Прокомментируйте метод проверки.
  2. Измените тест на:

    def test_validation(self, valid_contract_json):
    
        pprint.pprint(valid_contract_json)        
    
        seri = ContractSerializer(data=valid_contract_json).is_valid(raise_exception=True)
        # Serialization won't throw exception now
        pprint.pprint(seri.data)
    

Так я получуфактический вывод данных перед их передачей на Сериализатор и данные, подготовленные Сериализатором.

Вывод:

{
 'start_date': datetime.date(2019, 1, 1),
 'end_date': datetime.date(2019, 1, 31),
}

{
 'start_date': '2019-01-01',
 'end_date': None,
}

Я также проверил, если end_date уже Нет, когда validate() называется.Ответ ДА.

Итак, мой вопрос: почему сериализатор работает так, как ожидается с start_date, но не работает с end_date?

Может ли это быть проблемой скрытого кэша с pytest? РЕДАКТИРОВАТЬ:

Я пытался pytest --cache-clear, который не решил проблему, поэтому я подозреваю, что это не проблема чаше.

Заранее спасибо.

1 Ответ

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

я выяснил, почему произошла ошибка.

Проблема не была ни с pytest, ни с предоставленным прибором или процессом агрегации данных.

Проблема в том, что у меня был уровень поляпроверка выполняется следующим образом:

def validate_end_date(self, end_date):

    if end_date.day not in (14, monthrange(end_date.year, end_date.month)[1]):
        raise serializers.ValidationError()

Как вы можете видеть, это было плохо реализовано мной, так как я забыл вернуть значение поля, если проверка прошла успешно.Таким образом, значение поля стало None.

Извлеченный урок: при реализации проверки на уровне поля выполните НЕ , не забудьте вернуть начальное значение.

-> Methidпотом:

def validate_end_date(self, end_date):

    if end_date.day not in (14, monthrange(end_date.year, end_date.month)[1]):
        raise serializers.ValidationError()
    return start_date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...