2012-07-11 4 views
2

내 문제를 리디렉션하지 않습니다. 이보기를 실행하는 브라우저에서 URL을 입력하면 사용자가 인증되지 않은 경우 브라우저가 로그인 양식이 포함 된 URL로 올바르게 리디렉션됩니다. 그러나 브라우저는 이전 페이지로 리다이렉트하지 않으며 왜 이것이 작동하지 않는지 전혀 알지 못합니다. 나는 수백 가지의 것들을 시도했다. 긴 버전의장고 login_required 장식은 이전 페이지로 짧은 버전

내 문제 :

내가 하나의 앱 장고 프로젝트를,의는 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() 함수는 다음과 같다 : I는 템플릿, 예를 들어에 필요한 요소들을 포함 <input>

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 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') 

내 두 번째보기는 인증 된 사용자의 이메일 주소와 비밀번호를 변경하는 두 가지 형태를 렌더링합니다. 그것은 다음과 같습니다

@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) 

이 두 번째보기의 URL 패턴은 다음과 같습니다 I가 인증되지있을 때 나는 /account/에 액세스 할 때마다

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

, 나는 성공적으로 포함하는 메인 페이지로 이동 해요 로그인 양식. 결과 URL은 next 매개 변수가 포함 된 http://127.0.0.1:8000/?next=/account/입니다. 그러나 내 계정에 로그인 할 때도 여전히 기본 페이지에 있습니다. 로그인 양식에 필요한 next 매개 변수를 제공했지만 사용자 페이지로 리디렉션되지 않습니다. 이 매개 변수는 항상 비어있는 것 같지만 그 이유는 모르겠습니다. 또한 코드에서 다른 리디렉션 호출이 없습니다.

이 문제를 해결할 수 있습니까? 대단히 감사드립니다.

+0

사이드 노트 : 양식을 매우 이상한 방식으로 사용하는 것 같습니다. 'request.POST'에서'username'과'password'를 직접 가져 오는 대신, 폼을 인스턴스화 할 때'request.POST'를 사용하십시오. 즉,'form = AuthenticationForm (request.POST)'그리고'form.is_valid ()'. 이렇게하면 유효성 검사 (및 일부 위생 처리)가 발생하며'form-type '은 전혀 필요하지 않습니다. 암호가 잘못되어도 입력 된 사용자 이름이 기억되지 않는 코드의 현재 버그가 해결됩니다. – supervacuo

+0

자세한 내용은 [양식 작업] (https://docs.djangoproject.com/en/1.4/topics/forms/) 설명서를 참조하십시오. – supervacuo

답변

2

가능성이있는 답변이지만 리디렉션이 발생하지 않는 이유는 next 검색어 매개 변수를 사용하여 아무 것도하지 않는 것으로 보입니다.

사실, 그들은 뭔가 다른 할 시도처럼 성공적으로 사용자가 로그인, 당신은 (다른 컨텍스트 사전이기는하지만) 동일한 페이지를 보여 경우에 다음 Django docs explain으로

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) 

을, 매개 변수를 처리하는 contrib.auth.views.login() 함수이며 해당보기를 사용하고 있지 않습니다 (사용자가 혼동을 일으킬 정도로 동일하게 지정되었지만 contrib.auth.login함수).

당신도 단지 (처리 next뿐만 아니라, 또한 is_active를 확인,) 포함 된 뷰를 사용하거나 process_main_page_forms()으로는 인증 코드를 가져 아마 가치가있는 경우에, 당신의보기로 리디렉션 기능을 추가해야하면 않는 한 '다른 곳 _log_user_in()이 필요합니다 있는지 다시 :

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. 

귀하의 코드는 거의이다 :

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) 

example usage of contrib.auth.login하면 다음이 거기에, 당신은 "성공 페이지로 리디렉션"부분이 누락되었습니다. 여기는 next이 올 것입니다.

+0

답장을 보내 주셔서 대단히 감사합니다. 사실, 나는 로그인보기와 로그인 기능을 엉망으로 만들었다. 당신의 예제에서했던 것과 똑같은 방식으로 제안 된'HttpResponseRedirect' 호출을 코드에 포함 시켰습니다. 그러나 아무런 효과가 없습니다. 왜 그런지 알고 있니? – pemistahl

+0

그냥 작은 추가. 내가 로그인보기에 대해 읽었지만, 이해할 수있는 한,이보기가 올바르게 작동하려면 별도의 URL 패턴이 필요합니다. 그러나 고객이 요구하는 사항이므로 위에서 언급 한 세 페이지를 같은 페이지에 모두 포함해야합니다. 다른 생각? – pemistahl

+0

수수께끼. 왜 'return 문'을 치지 않는지 알아보기 위해 [Simon Willison의 Django 디버깅 기술] (http://simonwillison.net/2008/May/22/debugging/)을 시도해 볼 수 있습니다. 'print' 문이나'raise' 문은 제어 흐름에 어떤 문제가 있는지를 알려줄 것입니다.하지만 더 깊이 들어가야 할 경우'pdb'를 배우는 데 몇 분을 보내야합니다. – supervacuo