Приветствую.
Начал розбираться в ajax запросах в Django, и решил сделать валидацию поля логина при регистрации "на лету". "Методом тыка" написал вот такой код. И всё вроде работает правильно, но мне кажется есть более правильные пути для решения данной задачи (особенно во въюхе).
При изменении поля username в форме через jquery отправляется GET запрос на сервер, там валидируется и результат возвращается и отображается на странице.
urls.py
urlpatterns = [
....
url(r'^validate/username/$', validate_username, name='validate_username'),
]
views.py
def validate_username(request):
username = request.GET.get('username')
sign_up_fm = SignUpForm(request.GET)
data = {}
try: # Тут не уверен что правильно
for validator in sign_up_fm.fields['username'].validators:
validator(username)
except ValidationError as e:
data['info'] = e.message
if data.get('info'):
is_okey = False
else:
is_okey = True
data['info'] = 'Логин свободный' # если ошибок не было, то в data['info'] пусто
data['is_okey'] = is_okey
return JsonResponse(data)
forms.py
class SignUpForm(forms.ModelForm):
username = forms.CharField(max_length=30, required=True)
password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}))
confirm_password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}))
class Meta:
model = User
fields = ['username', 'password', 'confirm_password']
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['username'].validators.append(forbidden_usernames_validator)
self.fields['username'].validators.append(invalid_username_validator)
self.fields['username'].validators.append(unique_username_ignore_case_validator)
self.fields['username'].validators.append(username_length_max_validator)
self.fields['username'].validators.append(username_length_min_validator)
def clean(self):
super(SignUpForm, self).clean()
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if password and password != confirm_password:
self._errors['password'] = self.error_class(
['Пароли не совпадают!'])
return self.cleaned_data
def forbidden_usernames_validator(value):
forbidden_usernames = ['admin', ]
if value.lower() in forbidden_usernames:
raise ValidationError(u'Это зарезервирование слово')
def invalid_username_validator(value):
abc = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 'q', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_']
for i in range(len(value)):
if value[i] not in abc:
raise ValidationError(u'Недопустимые символы ( {} )'.format(value[i]))
def unique_username_ignore_case_validator(value):
if User.objects.filter(username__iexact=value).exists():
raise ValidationError('Логин занят')
def username_length_min_validator(value):
if len(value) < 4:
raise ValidationError('Логин слишком короткий')
def username_length_max_validator(value):
if len(value) > 20:
raise ValidationError('Логин слишком длинннный)
Дальше в шаблоне в зависимости от ответа всё отрисовуется.
Спасибо)