Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Дополнительная проверка. Переопределение метода clean. [RSS Feed]

#1 Ноя. 13, 2013 14:20:31

andrey16
Зарегистрирован: 2013-09-26
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

Допустим есть следующий код:

def is_positive_decimal(value):
    '''Разрешены десятичные числа, с 2 знаками после запятой/точки
    '''
    strng = str(value.replace(',', '.')).split('.')
    if all(str(i).isdigit() for i in strng):
        if len(strng) > 2:
            raise ValidationError(u'много точек/запятых')
        elif len(strng) == 2 and len(strng[1]) != 2:
            raise ValidationError(
                u'Количество чисел после запятой должно быть равно 2')
        elif len(strng) == 2 and int(strng[0]) == int(strng[1]) == 0:
            raise ValidationError(u'Введите2 положительное число!')
    else:
        raise ValidationError(u'Введите3 положительное число!')
class Person(models.Model):
    name = models.CharField(max_length=50, verbose_name=u'Человек')
    balance = models.CharField(
        max_length=50, verbose_name=u'Сумма',
        validators=[is_positive_decimal])
        
    def __unicode__(self):
        return self.name

если через админку попробуем сохранить объект класса Theft с money='0-9', но т.к. он у нас не пройдет валидацию is_positive_decimal, нам соответствующим образом укажут на ошибку.
class Theft(models.Model):
    name = select2.fields.ForeignKey(
        Person, verbose_name='Человек', ajax=True,
        search_field='name',
        overlay=u"выбираем человека", js_options={'quiet_millis': 100,},)
    money = models.CharField(
        max_length=50, verbose_name=u'Сумма',
        validators=[is_positive_decimal])
    
    def save(self, *args, **kwargs):
        self.money = self.money.replace('.', ',')
        if len(str(self.money).split(',')) == 1:
            self.money += ',00'
        super(Theft, self).save(*args, **kwargs)

если мы модифицируем код следующим образом:
class Theft(models.Model):
    name = select2.fields.ForeignKey(
        Person, verbose_name='Человек', ajax=True,
        search_field='name',
        overlay=u"выбираем человека", js_options={'quiet_millis': 100,},)
    money = models.CharField(
        max_length=50, verbose_name=u'Сумма',
        validators=[is_positive_decimal])
    
    def save(self, *args, **kwargs):
        self.money = self.money.replace('.', ',')
        if len(str(self.money).split(',')) == 1:
            self.money += ',00'
        super(Theft, self).save(*args, **kwargs)
    
    def clean(self):
        if float(self.name.balance.replace(',', '.')) < \
                        float(self.money(',', '.')):
                    raise ValidationError(
                        u'Остаток на счете меньше указанной суммы')

… и попробуем сохраниться теперь объект с money='0-9', то Джанго уже не будет объяснять нам по-хорошему, а вывалится со следующей ошибкой
Exception Value:
invalid literal for float(): 0-9

как поправить ситуацию?

Офлайн

#2 Ноя. 14, 2013 09:24:47

andrey16
Зарегистрирован: 2013-09-26
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

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

Офлайн

#3 Ноя. 14, 2013 09:44:48

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

Зачем деньги хранить как строку? Сделайте DecimalField, там есть max_digits и decimal_places.



Офлайн

#4 Ноя. 14, 2013 10:09:22

andrey16
Зарегистрирован: 2013-09-26
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

FishHook
Зачем деньги хранить как строку? Сделайте DecimalField, там есть max_digits и decimal_places.
это я знаю. но мне надо, чтобы можно было при вводе копейки от рублей отделялять хоть точкой, хоть запятой, а в базу сохранять с запятой.
но это меня сейчас не беспокоит.
меня интересует как заставить сначала проверять заполнены ли все поля, проходит ли поле с деньгами валидацию is_positive_decimal и уже только после всего этого выполнять все проверки из clean, дабы Джанго не вываливался с ошибкой.

Офлайн

#5 Ноя. 14, 2013 10:23:10

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

andrey16
это я знаю. но мне надо, чтобы можно было при вводе копейки от рублей отделялять хоть точкой, хоть запятой, а в базу сохранять с запятой.
Ну это вообще никак не дело модели какие-то там запятые от точек отделять. Все это делается в формах или в представлениях, но ни как не в модели.



Офлайн

#6 Ноя. 14, 2013 13:57:03

Dr.Livsi
От:
Зарегистрирован: 2010-02-15
Сообщения: 192
Репутация: +  3  -
Профиль   Отправить e-mail  

Дополнительная проверка. Переопределение метода clean.

сделайте деньги в моделях правильно - как decimal. Т.е. и money и balance. Далее в класс формы пишете метод:

    def clean_money(self):
        money = self.cleaned_data['money']
        if self.name.balance < money:
            raise ValidationError(u'Остаток на счете меньше указанной суммы')
        return money
Он проверяет конкретно поле money.



Офлайн

  • Начало
  • » Django
  • » Дополнительная проверка. Переопределение метода clean.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version