web-dev-qa-db-ja.com

Django:ユーザー名がすでに存在するかどうかを確認する方法

私はDjangoの上級ユーザーではありません。私はオンラインでさまざまな方法を見てきましたが、それらはすべて変更されたモデル用であるか、複雑すぎて理解できません。 UserCreationFormMyRegistrationFormを再利用しています

class MyRegistrationForm(UserCreationForm):

    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

    def save(self, commit=True):
        user = super(MyRegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.set_password(self.cleaned_data["password1"])

        if commit:
            user.save()

        return user

ユーザーが入力したユーザー名が既に使用されているかどうかを確認または確認する方法を見つけるのに苦労しています。だから私はこれを使用して、不正なユーザー名またはパスワードが一致しないと言っているhtmlにリダイレクトします:

def register_user(request):
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()

            return HttpResponseRedirect('/accounts/register_success')
        else:
            return render_to_response('invalid_reg.html')


    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()
    print args
    return render_to_response('register.html', args)

これが私の登録テンプレートです(必要な場合):

{% extends "base.html" %}

{% block content %}

<section>
<h2 style="text-align: center">Register</h2>
<form action="/accounts/register/" method="post">{% csrf_token %}

<ul>
{{form.as_ul}}
</ul>
<input type="submit" value="Register" onclick="validateForm()"/>

</form>

</section>
{% endblock %}

しかし、ユーザーがリダイレクトされる前に、そのような例外やsmthを発生させる必要があります。おそらく、ユーザーが登録を押すと、ユーザー名が既に使用されているというエラー/警告が表示されますか?それは可能ですか?

12
pptt

exists を使用できます:

from Django.contrib.auth.models import User

if User.objects.filter(username=self.cleaned_data['username']).exists():
    # Username exists
    ...
19

usernameclean_usernameメソッドで存在するかどうかを確認し、ValidationErrorを発生させることができます。

def clean_username(self, username):
    user_model = get_user_model() # your way of getting the User
    try:
        user_model.objects.get(username__iexact=username)
    except user_model.DoesNotExist:
        return username
    raise forms.ValidationError(_("This username has already existed."))

この場合、errorを登録フォームに表示でき、別のページにリダイレクトする必要はありません。

更新:

@Spacedmanによると、フォームレベルのユーザー名の一意性をDBレベルに対してチェックする際の競合状態に関する有効なポイントを指摘しましたが、これを取得する可能性は非常に低いですが、ここで行う場合、関連するSOの回答が読む価値があります:

Djangoの一意のチェックで競合状態を回避する方法

Djangoのレース条件

別のアップデート

OPのコメントに従って、ビューに別の変更を加えることができます。

def register_user(request):
    # be DRY, the form can be reused for both POST and GET
    form = MyRegistrationForm(request.POST or None)

    # check both request is a POST and the form is valid
    # as you don't need to redirect for form errors, remove else block
    # otherwise it's going to redirect even form validation fails
    if request.method == 'POST' and form.is_valid():
        form.save()
        return HttpResponseRedirect('/accounts/register_success')
    # I use render so need not update the RequestContext, Django does it for you
    html = render(request, 'register.html', {'form': form})
    return HttpResponse(html)

お役に立てれば。

5
Anzel