Django - лучший способ справиться с проверками достоверности при создании модели - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь выяснить, как использовать проверки при создании объекта в django.

Из моего POV есть 2 подхода:

  1. Переопределить значение по умолчанию validate_fieldметод сериализаторов DRF.
  2. Добавьте валидаторы уровня поля к моделям и перехватывайте любые исключения IntegrityError или ValidationError, когда сериализатор вызывает .save() метод модели.

Кажется, что оба способаесть свои минусы.

При использовании подхода 1 мои модели остаются "незащищенными" от любых других вызовов .create() модели, кроме сериализаторов. Подход 2 имеет дело с вышеупомянутой проблемой, но делает код более сложным, поскольку обработка исключений необходима в методе .create() сериализатора.

Есть ли кто-нибудь, кто сталкивался с подобной проблемой и / илинашли «чище» способ борьбы с этим?

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

Насколько я понял, вам нужна проверка модели Django.Вы можете попробовать этот подход (я думаю, это именно то, что вы хотите).

from django.core.exceptions import ValidationError

class Foo(models.Model):
    name = models.CharField(max_length=255)

    def clean(self):
        raise ValidationError('Problem during validation')

f = Foo(name='test')
f.full_clean() # This is what you need. f.clean() will be enough, but f.full_clean() will make field level validations (run validators) and checking about uniqueness also.
f.save()

В общем Django никогда не делает проверки на уровне модели (не вызывает full_clean()), во времясоздание модели.

f = Foo(**fields_dict)
f.save() # no validation performed.

назовите его сами, если хотите ,,,

f = Foo(**fields_dict)
f.full_clean() # validation performed
f.save()

full_clean() метод выполняется автоматически, если вы используете класс ModelForm.Это дополнительный хук Джанго .

0 голосов
/ 21 мая 2019

Я думаю, что перемещение валидаций вниз к модели - это самый безопасный способ обеспечить наивысший уровень надежности, потому что валидации будут применяться до тех пор, пока они выполняются через Джанго (если вы используйте сериализаторы, проверки не будут работать, если пропущена Django Rest Framework ).

Проверки уровня модели могут быть:

Проверка на уровне поля : Вы создаете метод, который выполняет проверку, и задаете такой метод, как средство проверки поля:

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

def validate_even(value):
    if value % 2 != 0:
        raise ValidationError(
            _('%(value)s is not an even number'),
            params={'value': value},
        )

from django.db import models

class MyModel(models.Model):
    even_field = models.IntegerField(validators=[validate_even])

Проверки на уровне модели : вы переопределяете метод clean() модели и выполняете необходимые проверки:

import datetime
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

class Article(models.Model):
    ...
    def clean(self):
        # Don't allow draft entries to have a pub_date.
        if self.status == 'draft' and self.pub_date is not None:
            raise ValidationError(_('Draft entries may not have a publication date.'))
        # Set the pub_date for published items if it hasn't been set already.
        if self.status == 'published' and self.pub_date is None:
            self.pub_date = datetime.date.today()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...