2

短いバージョンでの私の問題:

login_requiredビューの 1 つにデコレータを追加しました。このビューを実行するブラウザに URL を入力すると、ユーザーが認証されていない場合、ブラウザはログイン フォームを含む URL に正しくリダイレ​​クトされます。ただし、ブラウザーが前のページにリダイレクトされることはなく、なぜこれが機能しないのかわかりません。私は何百ものことを試しました。

長いバージョンでの私の問題:

単一のアプリを含む Django プロジェクトがあります。それを と呼びましょうmy_app。私のプロジェクトのすべてのテンプレートは にありますtemplates/my_app/main.htmlログインフォームを含むいくつかのフォームを含むというテンプレートがあります。という追加のPOSTパラメーターform-typeを使用して、どのフォームが送信されたかを確認します。コードは次のようになります。

def process_main_page_forms(request):

    if request.method == 'POST':
        if request.POST['form-type'] == u'login-form':
            template_context = _log_user_in(request)

        elif request.POST['form-type'] == u'registration-form':
            template_context = _register_user(request)

        elif request.POST['form-type'] == u'password-recovery-form':
            template_context = _recover_password(request)

    else:
        template_context = {
            'auth_form': AuthenticationForm(),
            'registration_form': RegistrationForm(),
            'password_recovery_form': EmailBaseForm()
        }

    return render(request, 'my_app/main.html', template_context) 

関数_log_user_in()は次のようになります。

def _log_user_in(request):

    message = ''
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)

    if user is not None:
        if user.is_active:
            login(request, user)
        else:
            message = 'Your account has been disabled. ' \
                      'Please contact the administrator.'
    else:
        message = 'Your username and password didn\'t match. Please try again.'

    template_context = {
        'auth_form': AuthenticationForm(),
        'registration_form': RegistrationForm(),
        'password_recovery_form': EmailBaseForm(),
        'message': message,
}

    return template_context

また、必要な<input>要素をテンプレートに含めます。たとえば、ログイン フォームの場合は次のようになります。

<input type="hidden" name="form-type" value="login-form" />
<input type="hidden" name="next" value="{{ next }}" />

このビューの URL パターンは次のとおりです。

url(r'^$', process_main_page_forms, name='main-page')

2 番目のビューは、認証済みユーザーのメール アドレスとパスワードを変更するための 2 つのフォームをレンダリングします。次のようになります。

@login_required(login_url='/')
def change_user_credentials(request):

    if request.method == 'POST':

        if request.POST['form-type'] == u'change-email-form':
            template_context = _change_email_address(request)

        elif request.POST['form-type'] == u'change-password-form':
            template_context = _change_password(request)

    else:
        template_context = {'change_email_form': ChangeEmailForm()}

    return render(request, 'my_app/user.html', template_context)

この 2 番目のビューの URL パターンは次のとおりです。

url(r'^account/$', change_user_credentials, name='user-page')

認証されていないときにアクセス/account/すると、ログイン フォームを含むメイン ページに正常にリダイレクトされます。結果の URL にはhttp://127.0.0.1:8000/?next=/account/、必要なnextパラメーターが含まれています。ただし、アカウントにログインすると、まだメイン ページにいます。nextログインフォームで必要なパラメーターを指定したにもかかわらず、ユーザーページにリダイレクトされることはありません。このパラメーターは常に空のようですが、理由はわかりません。私のコードには、他のリダイレクト呼び出しもありません。

この問題を解決するのを手伝ってくれませんか? 事前にどうもありがとうございました。

4

1 に答える 1

2

nextおそらく陳腐な答えですが、リダイレクトが発生しない理由は、クエリパラメーターで何もしていないように見えるためです。

実際、ユーザーが正常にログインした場合、別のことを試みたかのように同じページを表示します (コンテキスト辞書は異なりますが)。

def process_main_page_forms(request):
    if request.method == 'POST':
        if request.POST['form-type'] == u'login-form':
            template_context = _log_user_in(request)

        ...
    ...

    return render(request, 'my_app/main.html', template_context) 

Djangoのドキュメントが説明しているように、パラメータcontrib.auth.views.login()を処理するのは関数でnextあり、そのビューを使用していません(紛らわしい同じ名前の関数を使用していますが)。contrib.auth.login

含まれているビュー (処理に加えてnextもチェックしますis_active) を使用するか、リダイレクト機能をビューに追加するprocess_main_page_forms()必要があります。_log_user_in()他の場所:

from django.http import HttpResponseRedirect
from django.conf import settings

def process_main_page_forms(request):
    if request.method == 'POST':
        if request.POST['form-type'] == u'login-form':
            username = request.POST['username']
            password = request.POST['password']

            user = authenticate(username=username, password=password)

            if user is not None:
                if user.is_active:
                    login(request, user)
                    if request.GET.get('next', False):
                        return HttpResponseRedirect(request.GET.get('next'))
                    else:
                        return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
                else:
                    message = 'Your account has been disabled.'
            else:
                message = 'Your username and password didn\'t match. Please try again.'

            # If we've reached this point then the login failed
            template_context = {
                'auth_form': AuthenticationForm(),
                'registration_form': RegistrationForm(),
                'password_recovery_form': EmailBaseForm(),
                'message': message,
            }
        elif ...:
            # Do things with other form types
    else:

    return render(request, 'my_app/main.html', template_context)

使用例contrib.auth.loginは次のとおりです。

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
    else:
        # Return an 'invalid login' error message.

あなたのコードはほとんどそこにありますが、「成功ページへのリダイレクト」の部分が欠けていましたnext

于 2012-07-11T18:57:48.913 に答える