2013-11-15 13 views
9

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

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) 

спасибо.

ответ

22

Когда 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) 

Рассмотрите возможность использования метода .exists, поскольку он выдает более быстрый запрос к базе данных, чем если вы пытаетесь получить всю информацию о пользователе с помощью метода .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 

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

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

+0

Спасибо, человек, это именно то, что я искал. – lukas

+0

Heyyy @lukas также может выполнять 'if User.objects.filter (username = username) .count()' – wonderwhy

0

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

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}) 
Смежные вопросы