2014-02-11 5 views
7

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

Я хочу, чтобы сделать любое количество следующих (как термин в следующем параметре):

[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> profile. 
[not signed in] -> newsfeed -> login?next=/newsfeed/` -> auth -> newsfeed. 

В то время как я в настоящее время идет:

[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> loggedin 
[not signed in] -> newsfeed -> login?next=/newsfeed/ -> auth -> loggedin 

Я ищу каким-то образом передать next параметр от login до auth и имеют auth перенаправить к этому параметру

В настоящее время я пытаюсь в моих login.html:

<input type='text' name="next" value="{{ next }}"> 

однако это не получает следующее значение. Я могу видеть на панели отладки инструмента:

GET data 
Variable Value 
u'next'  [u'/accounts/profile/'] 

views:

def auth_view(request): 
    username = request.POST.get('username', '') 
    password = request.POST.get('password', '') 
    user = auth.authenticate(username=username, password=password) 

    if user is not None: 
    auth.login(request, user) 
    print request.POST 
    return HttpResponseRedirect(request.POST.get('next'),'/accounts/loggedin') 
    else: 
    return HttpResponseRedirect('/accounts/invalid') 

login.html:

{% extends "base.html" %} 

{% block content %} 

    {% if form.errors %} 
    <p class="error"> Sorry, you have entered an incorrect username or password</p> 
    {% endif %} 
    <form action="/accounts/auth/" method="post">{% csrf_token %} 
    <label for="username">User name:</label> 
    <input type="text" name="username" value="" id="username"> 

    <label for="password">Password:</label> 
    <input type="password" name="password" value="" id="password"> 

    <input type='text' name="next" value="{{ request.GET.next }}"> 
    <input type="submit" value="login"> 
    </form> 

{% endblock %} 

settings:

from django.conf.urls import patterns, include, url 

from django.contrib import admin 
admin.autodiscover() 

urlpatterns = patterns('', 
    # Examples: 

    url(r'^admin/', include(admin.site.urls)), 
    ('^accounts/', include('userprofile.urls')), 

    url(r'^accounts/login/$', 'django_yunite.views.login'), 
    url(r'^accounts/auth/$', 'django_yunite.views.auth_view'), 
    url(r'^accounts/logout/$', 'django_yunite.views.logout'), 
    url(r'^accounts/loggedin/$', 'django_yunite.views.loggedin'), 
    url(r'^accounts/invalid/$', 'django_yunite.views.invalid_login'), 

) 

settings:

# Build paths inside the project like this: os.path.join(BASE_DIR, ...) 
import os 
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 

# SECURITY WARNING: don't run with debug turned on in production! 
DEBUG = True 

TEMPLATE_DEBUG = True 

ALLOWED_HOSTS = [] 


# Application definition 

INSTALLED_APPS = (
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'debug_toolbar', 
    'userprofile', 
) 

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
) 

ROOT_URLCONF = 'django_yunite.urls' 

WSGI_APPLICATION = 'django_yunite.wsgi.application' 

# Internationalization 
# https://docs.djangoproject.com/en/1.6/topics/i18n/ 

LANGUAGE_CODE = 'en-ca' 

TIME_ZONE = 'EST' 

USE_I18N = True 

USE_L10N = True 

USE_TZ = True 


# Static files (CSS, JavaScript, Images) 
# https://docs.djangoproject.com/en/1.6/howto/static-files/ 

STATIC_URL = '/static/' 

STATICFILES_DIRS = (
    ('assets', '/home/user/GitHub/venv_yunite/django_yunite/static/'), 
    ) 

TEMPLATE_DIRS = (
    './templates', 
    '/article/templates', 
) 

STATIC_ROOT = "/home/user/Documents/static/" 

AUTH_PROFILE_MODULE = 'userprofile.UserProfile' 

печати Постулаты показывает пустой u'next'

+0

Mind your ')', 'return HttpResponseRedirect (request.POST.get ('next'), '/ accounts/loggedin')' должен быть 'return HttpResponseRedirect (request.POST.get ('next', '/ счета/loggedin ')) ' –

+0

что нет? Зачем? также это не решает проблему. Проблема по какой-либо причине не указана в следующем параметре. {{request.GET.next}} ничего не возвращает –

+0

Обновите вопрос с помощью 'settings.py'. –

ответ

7

Строка запроса неявно передается в любом виде, без необходимости писать какие-либо специальные код.

Все, что вам нужно сделать, это убедиться, что ключ next передается от фактической формы входа (в вашем случае, это форма, которая отображается в /accounts/login/), к /accounts/auth зрения.

Для этого вам необходимо убедиться, что в ваших настройках включен контекстный процессор шаблона запроса (django.core.context_processors.request). Чтобы сделать это, сначала нужно импортировать значения по умолчанию для TEMPLATE_CONTEXT_PROCESSORS, затем добавить процессор запрос к нему в вашем settings.py, как это:

from django.conf import global_settings 

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    "django.core.context_processors.request", 
) 

Тогда в виде:

<form method="POST" action="/accounts/auth"> 
    {% csrf_token %} 
    <input type="hidden" name="next" value="{{ request.GET.next }}" /> 
    {{ login_form }} 
    <input type="submit"> 
</form> 

Теперь, в вашем /accounts/auth вид:

def foo(request): 
    if request.method == 'POST': 
     # .. authenticate your user 


     # redirect to the value of next if it is entered, otherwise 
     # to /accounts/profile/ 
     return redirect(request.POST.get('next','/accounts/profile/')) 
+0

Это именно то, что я думал, но мое {{request.GET.next}} пусто. Я отредактирую и опубликую по коду –

+0

Его 'request.GET',' request.Get' не будет работать, и вам нужно убедиться, что у вас включен обработчик контекстного шаблона (по умолчанию он не включен). –

+0

мои извинения опечатки в комментариях. Код размещен выше –

3

Что вы ищете является login decorator.

В вашем views.py

from django.contrib.auth.decorators import login_required 

@login_required(login_url="/accounts/login/") 
def profile(request): 
    """your view code here""" 
    return HttpResponse("boo ya", "text/html") 

Затем в urls.py добавить URL аутентификации

(r'^accounts/login/$', 'django.contrib.auth.views.login'), 

Наконец: Убедитесь, что вы django.contrib.auth в установленных вами приложениях и установленном AuthenticationMiddleware.

settings.py

INSTALLED_APPS = (
    -- snip --, 
    'django.contrib.auth', 
    ) 


MIDDLEWARE_CLASSES = (
    -- snip --, 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    ) 

ваш шаблоны/регистрация/login.html

<form method="POST" action="/accounts/login/"> 
    {% csrf_token %} 
    <input type="hidden" name="next" value="{{ next }}" /> 
    {{ login_form }} 
    <input type="submit"> 
</form> 
+1

У меня уже есть это. Проблема заключается не в том, чтобы маршрутизироваться (в вашем примере) «boo ya». Я хочу перейти на страницу, к которой я пытался перейти, прежде чем я был вынужден вернуться к '@ login_required', который должен храниться в« следующем »значении так или иначе –

0

То, что я сделал, это следующее. Для меня это похоже на взломанную работу. Есть ли лучший способ использовать логин с помощью csrf?

views:

def login(request): 
    c={} 
    c.update(csrf(request)) 
    if 'next' in request.GET: 
    c['next'] = request.GET.get('next') 
    return render_to_response('login.html', c) 

def auth_view(request): 
    username = request.POST.get('username', '') 
    password = request.POST.get('password', '') 
    user = auth.authenticate(username=username, password=password) 

    if user is not None: 
    auth.login(request, user) 

    if request.POST.get('next') != '': 
     return HttpResponseRedirect(request.POST.get('next')) 
    else: 
     return HttpResponseRedirect('/accounts/loggedin') 
    else: 
    return HttpResponseRedirect('/accounts/invalid') 

login.html:

<input type="hidden" name="next" value="{{ next }}"/> 
0

Столкнувшись Аналогичная ситуация некоторое время назад. Чтобы решить эту проблему, я написал свой собственный декоратор -

def validate_request_for_login(f): 
    def wrap(request): 
     if not request.user.is_authenticated(): 
      return redirect("/login?next=" + request.path) 
     return f(request) 
    return wrap 

Над декоратором проверяет аутентификацию пользователя. Если пользователь не аутентифицирован, перенаправите пользователя на страницу входа, передав url из объекта запроса.

Смежные вопросы