1. ivanff.myopenid.com

    13.03.2010

    0 ↑
    2 ↓
    Как-то можно это сократить?
    class FinanceJAdminForm(forms.ModelForm):

    # inn = forms.RegexField(min_length=10, max_length=10, regex=r'^[0-9]*$')
    # inn.error_messages = {'invalid': 'Неправильный формат ИНН, введите 10 цифр'}

    def __init__(self, *args, **kwargs):
    super(FinanceJAdminForm, self).__init__(*args, **kwargs)

    #http://hramy.ru/regions/regfull.htm
    self.state_codes = list(xrange(1,96))

    # ИНН
    kwargs = self.fields['inn'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат ИНН, убедитесь, что это значение
    содержит 10 цифр'''}})
    self.fields['inn'] = forms.RegexField(r'^[0-9]{10}$', **kwargs)

    # КПП
    kwargs = self.fields['kpp'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат КПП, убедитесь, что это значение
    содержит 9 цифр'''}})
    self.fields['kpp'] = forms.RegexField(r'^[0-9]{9}$', **kwargs)

    # Юридической аддресс (Пример: 123456, Пенза, ул.Собачкина, д.13а)
    kwargs = self.fields['legal_address'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': 'Неправильный формат адреса, следуйте примеру'}})
    import re
    regex = re.compile(u'^[0-9]{6}, [-\w]+, ул\.[-\w]+, д.[0-9]+.*$', re.UNICODE | re.IGNORECASE)
    self.fields['legal_address'] = forms.RegexField(regex, **kwargs)

    # ОКПО (Пример: 58622444)
    kwargs = self.fields['okpo'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат ОКПО, убедитесь, что это значение
    содержит 8 или 10 цифр'''}})
    self.fields['okpo'] = forms.RegexField(r'^([0-9]{8}|[0-9]{10})$', **kwargs)

    #ОГРН (Пример: 1062336004136)
    kwargs = self.fields['ogrn'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат ОГРН, убедитесь, что это значение
    содержит 13 цифр'''}})
    self.fields['ogrn'] = forms.RegexField(r'^[0-9]{13}$', **kwargs)

    #БИК (Пример: 044583267)
    kwargs = self.fields['bik'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат БИК, убедитесь, что это значение
    содержит 9 цифр'''}})
    self.fields['bik'] = forms.RegexField(r'^[0-9]{9}$', **kwargs)
    # Кор. счет (Пример: 30101810400000000267)
    kwargs = self.fields['kor_account'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат Корреспондентского счёта,
    убедитесь, что это значение содержит 20 цифр'''}})
    self.fields['kor_account'] = forms.RegexField(r'^[0-9]{20}$', **kwargs)
    # Рас. счет (Пример: 40702810800000004708) #больше валидации не знаю
    kwargs = self.fields['ras_account'].__dict__
    kwargs.pop('creation_counter')
    kwargs.update({'error_messages': {'invalid': '''Неправильный формат Расчётного счёта,
    убедитесь, что это значение содержит 20 цифр'''}})
    self.fields['ras_account'] = forms.RegexField(r'^[0-9]{20}$', **kwargs)

    def clean_inn(self):
    _inn = self.cleaned_data['inn']
    if sum(int(i) for i in _inn) == 0:
    raise forms.ValidationError('Неправильный формат ИНН, контрольное число неверно')
    if len(_inn) == 10:
    factor = ((2, 4, 10, 3, 5, 9, 4, 6, 8),)
    elif len(_inn) == 12:
    factor = ((7, 2, 4, 10, 3, 5, 9, 4, 6, 8), (3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8),)
    else:
    raise forms.ValidationError('Неправильный формат ИНН')
    for f,i in zip(factor, (len(_inn)-len(f) for f in factor)):
    crc = sum(map(lambda x,y: x*int(y), f, _inn[:-i])) % 11 % 10
    if crc != int(_inn[-i]):
    raise forms.ValidationError('Неправильный формат ИНН, контрольное число неверно')
    return _inn

    def clean_kpp(self):
    _kpp = self.cleaned_data['kpp']
    kp_codes = list(xrange(1,9)) + list(xrange(30,85))

    state = int(_kpp[0:2])
    kp = int(_kpp[2:4])

    if state not in self.state_codes:
    raise forms.ValidationError('Неправильный формат КПП, неправильный код субъекта РФ')
    elif kp not in kp_codes:
    raise forms.ValidationError('Неправильный формат КПП, неправильный код причины постановки на учет')
    return _kpp

    def clean_ogrn(self):
    _orgn = self.cleaned_data['ogrn']
    state = int(_orgn[3:5])
    if state not in self.state_codes:
    raise forms.ValidationError('Неправильный формат ОГРН, неправильный код субъекта РФ')
    crc = int(_orgn[:-1]) % 11 % 10
    if crc != int(_orgn[-1]):
    raise('Неправильный формат ОГРН, контрольное число неверно')
    return _orgn

    def clean_bik(self):
    _bik = self.cleaned_data['bik']
    if _bik[:2] != '04':
    raise forms.ValidationError('Неправильный формат БИК, первые 2 цифры - код Российской Федерации (04)')
    if not (50 <= int(_bik[-3:]) <= 999):
    raise forms.ValidationError('Неправильный формат БИК, неправильный условный номер кредитной организации')
    return _bik

    def clean(self):
    super(FinanceJAdminForm, self).clean()
    errors = False
    _kor_account = self.cleaned_data['kor_account']
    _bik = self.cleaned_data['bik']
    if _kor_account[-3:] != _bik[-3:]:
    self._errors['bik'] = self._errors.get('bik', ErrorList())
    self._errors['bik'].append(u'Ошибка')
    self._errors['kor_account'] = self._errors.get('kor_account', ErrorList())
    self._errors['kor_account'].append(u'Ошибка')
    errors = True
    if errors:
    raise forms.ValidationError('Неправильное значение БИК или Кор. счет')

    class Meta:
    exclude=('shop',)
    model = FinanceJModel
  2. А зачем эти вот страшные повторяющиеся куски в __init__?

  3. admin

    13.03.2010

    1 ↑
    0 ↓
    очевидно, что ИНН, по своей сути, это не является Regexp'ом.
    следуя логике ооп, вместо forms.RegexpField в форму просится, нечто вроде forms.InnField . задачка не на сокращение, а на декомпозицию, имхо.

    http://docs.djangoproject.com/en/dev/ref/forms/fields/#creating-custom-fields (на самом деле смотреть исходники django/forms/fields.py ).
  4. ivanff.myopenid.com

    13.03.2010

    0 ↑
    1 ↓
    Инн только в этой модели используется, влом писать поле модели :)
    кстати там не только ИНН валидация, а вся вообще которую только удалось нарыть в инете :)
    че за слешный куски?
    __dict__ для того чтобы не перебивать агрументы которые передаются в поле модели, в поля формы :)
  5. admin

    14.03.2010

    2 ↑
    0 ↓
    Инн только в этой модели используется, влом писать поле модели :)
    Возможность повторно использовать ранее написанный код это полезное следствие модульности, но не её цель. Декомпозиция нужна для того, чтобы не думать в панике о большой и сложной задаче, а размеренно решать маленькие и простые. )) Или не очень простые. В соседней теме Dmitry упомянул КЛАДР http://www.gnivc.ru/Document.aspx?id=80 — предлагаю как повод для того, чтобы подумать над валидацией адресов отдельно — ведь адрес, который содержит в аккурат "ул." и "д." это ну очень частный случай. :)
    кстати там не только ИНН валидация, а вся вообще которую только удалось нарыть в инете
    Тем более не нужно хоронить такие замечательные алгоритмы где-то внутри формы. Есть смысл разобрать ее на части и оформить все это исследование в отдельную библиотеку. ;)

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.