Проверка наличия имени пользователя в Django

Я работаю над проектом Django, где пользователи смогут изменять свои имена пользователей вместе с их именем и фамилией в одной форме. В forms.py, я пытаюсь выяснить, существует ли пользователь. Если это так, он должен отображать ошибку. Проблема в том, что если пользователь хочет изменить его имя и фамилию и оставляет свое имя на входе, это вызывает ошибку проверки. Очевидно, что имя пользователя уже существует. Есть ли способ проверить, равно ли оно имени пользователя текущего зарегистрированного пользователя и во избежание ошибки?

class ChangeNameForm(forms.ModelForm):
    username = forms.CharField(max_length=30)
    first_name = forms.CharField(max_length=255)
    last_name = forms.CharField(max_length=255)

    def clean_username(self):
        username = self.cleaned_data['username']

        try:
            user = User.objects.get(username=username)
        except user.DoesNotExist:
            return username
        raise forms.ValidationError(u'Username "%s" is already in use.' % username)

спасибо.

2 ответов


когда ModelForms привязаны к объекту модели, они имеют атрибут, называемый "экземпляр", который является самим объектом модели. На ваш взгляд, когда request.method == 'POST', вы, вероятно, создаете экземпляр формы следующим образом:

form = ChangeNameForm(request.POST, instance=request.user)

если это так, вы можете получить доступ к зарегистрированному пользователю из методов формы, и ваш метод проверки может быть чем-то вроде этого:

def clean_username(self):
    username = self.cleaned_data['username']
    try:
        user = User.objects.exclude(pk=self.instance.pk).get(username=username)
    except User.DoesNotExist:
        return username
    raise forms.ValidationError(u'Username "%s" is already in use.' % username)

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

def clean_username(self):
    username = self.cleaned_data['username']
    if User.objects.exclude(pk=self.instance.pk).filter(username=username).exists():
        raise forms.ValidationError(u'Username "%s" is already in use.' % username)
    return username

дополнительно, вы также можете следовать эти директивы при повышении ValidationError.

Я не могу проверить этот код прямо сейчас, поэтому извиняюсь, если что-то не так.


вот как мне удалось заставить его работать (при условии, что у вас есть зарегистрированный пользователь):

forms.py

from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import User

class MyUserChangeForm(UserChangeForm):
    def __init__(self, *args, **kwargs):
        super(MyUserChangeForm, self).__init__(*args, **kwargs)
        del self.fields['password']

    class Meta:
        model = User
        fields = ('username', 'first_name')

views.py

def home(request):
    if request.method == 'POST':
        form = MyUserChangeForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
    else:
        form = MyUserChangeForm(instance=request.user)

    return render(request, 'change_user.html', {"form": form})