-
Как-то можно это сократить?
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 -
А зачем эти вот страшные повторяющиеся куски в __init__?
-
очевидно, что ИНН, по своей сути, это не является Regexp'ом.
следуя логике ооп, вместо forms.RegexpField в форму просится, нечто вроде forms.InnField . задачка не на сокращение, а на декомпозицию, имхо.
http://docs.djangoproject.com/en/dev/ref/forms/fields/#creating-custom-fields (на самом деле смотреть исходники django/forms/fields.py ). -
Инн только в этой модели используется, влом писать поле модели :)
кстати там не только ИНН валидация, а вся вообще которую только удалось нарыть в инете :)
че за слешный куски?
__dict__ для того чтобы не перебивать агрументы которые передаются в поле модели, в поля формы :) -
Инн только в этой модели используется, влом писать поле модели :)Возможность повторно использовать ранее написанный код это полезное следствие модульности, но не её цель. Декомпозиция нужна для того, чтобы не думать в панике о большой и сложной задаче, а размеренно решать маленькие и простые. )) Или не очень простые. В соседней теме Dmitry упомянул КЛАДР http://www.gnivc.ru/Document.aspx?id=80 — предлагаю как повод для того, чтобы подумать над валидацией адресов отдельно — ведь адрес, который содержит в аккурат "ул." и "д." это ну очень частный случай. :)
Тем более не нужно хоронить такие замечательные алгоритмы где-то внутри формы. Есть смысл разобрать ее на части и оформить все это исследование в отдельную библиотеку. ;)кстати там не только ИНН валидация, а вся вообще которую только удалось нарыть в инете
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

