web-dev-qa-db-ja.com

ユーザー名がDjangoに存在するかどうかを確認しています

私はDjangoプロジェクトに取り組んでいます。このプロジェクトでは、ユーザーはユーザー名と姓名を1つのフォームで変更できます。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)

ありがとうございました。

15
lukas

ModelFormがモデルオブジェクトにバインドされると、モデルオブジェクト自体である「インスタンス」と呼ばれる属性を持ちます。あなたの見解では、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

オプションで、ValidationErrorを発生させるときに これらのガイドライン に従うこともできます。

現在、このコードをテストすることはできないので、何か問題があればお詫びします。

27
Victor Silva

これは私がそれをうまく機能させる方法です(あなたがログインしたユーザーを持っていると仮定します):

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})
0
mariodev