Задать вопрос

Как я могу улучшить данный код?

Приветствую.
Начал розбираться в 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('Логин слишком длинннный)


Дальше в шаблоне в зависимости от ответа всё отрисовуется.

Спасибо)
  • Вопрос задан
  • 533 просмотра
Подписаться 4 Оценить 5 комментариев
Пригласить эксперта
Ответы на вопрос 1
@Xander017
Вот это вот можно сделать
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]))


вот по такому примеру:
import re

c = "Иван"

if re.search('^[A-Za-z0-9]*$',c, re.UNICODE):  
 # если нужны только маленькие латинские [a-z0-9]
    # do something
else:
   # do something
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы