Подтвердить что ты не робот

Система Django rest & model validation

Начало работы с использованием django-rest-framework, и у меня возникают некоторые проблемы с проверкой.

У меня есть базовая модель, и я применил валидаторы к совокупности своих полей (регулярный MaxLengthValidator и пользовательский RegexValidator, в итоге чего-то вроде этого:

class ZipCodeValidator(RegexValidator):
    regex = '^([0-9]{5})$'
    message = u'Invalid ZipCode.'


class User(AbstractUser, BaseUser):
    """
    Custom user model
    """

    # ... other fields ...
    zipcode = models.CharField(
        max_length=5, blank=True, validators=[ZipCodeValidator()]
    )
    description = models.TextField(
        null=True, blank=True, max_length=1000, validators=[MaxLengthValidator(1000)]
    )

Затем я создал a ModelSerializer, сопоставленный с этой моделью, с несколькими дополнительными полями и методами. Все это обслуживается очень простым `RetrieveUpdateAPIView.

Я замечаю, что валидаторы не вызываются (я могу ввести что-либо в поле zipcode или превысить 1000 символов для описания).

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

class UserSerializer(serializers.ModelSerializer):
    zipcode = serializers.WritableField(
        source='zipcode', required=False, validators=[ZipCodeValidator()]
    )
    description = serializers.WritableField(
        source='description', required=False, validators=[MaxLengthValidator(1000)]
    )

Это отлично работает, но мне это не нравится. Я бы предпочел, чтобы эта проверка выполнялась на уровне модели, чтобы быть более безопасной (у меня не было бы разума или дополнительной проверки на сериализаторе, но эти правила должны быть соблюдены во всех случаях). Поскольку сериализаторы работают так же, как формы django, я ожидал, что они вызовут модель clean и метод cie, прежде чем сохранять их, но быстрый взгляд на источник , кажется, указывает это не так.

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

Мне может быть что-то не хватает, но есть ли хороший и чистый способ гарантировать, что эти валидаторы будут выполняться сериализатором перед обновлением модели?

EDIT: Doubled проверил источник, выяснилось, что метод экземпляра full_clean действительно вызывается представлением перед сохранением его в db, который по очереди заканчивает работу с валидатором модели. Все еще потеряно, почему те, кажется, не бегут, tho.

4b9b3361

Ответ 1

Это работает для меня:

class ZipCodeValidator(RegexValidator):
    regex = r'^[0-9]{5}$'
    message = 'Invalid ZipCode.'


class MyModel(models.Model):
    zipcode = models.CharField(max_length=5, blank=True, validators=[ZipCodeValidator()])


class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel


>>> s1 = MyModelSerializer(data={'zipcode': '34234'})
>>> s1.is_valid()
True
>>> s2 = MyModelSerializer(data={'zipcode': 'f3434'})
>>> s2.is_valid()
False
>>> s2.errors
{'zipcode': [u'Invalid ZipCode.']}