简体   繁体   中英

login_required Django redirect next not working

Hello. I try to redirect user to the page he wants before he login, by login_required but the page doesn't redirecting! I have searched a lot but I found nothing. Here my main codes for login_required: I summarized them to the related subject. If need to add something else, tell me. Thank you in advance.

VIEW:

from django.contrib.auth.decorators import login_required

def user_login(request):
    next_url = request.GET.get('next')
    print(next_url)
    if request.method == 'POST':
        form = UserLoginForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(request, username=cd['username'], password=cd['password'])
            if user is not None:
                login(request, user)
                messages.success(request, 'Login Successful', extra_tags='success')
                if next_url:
                    return redirect(next_url)
                return redirect('post:all_posts')
            else:
                messages.error(request, 'Wrong Username Or Password', extra_tags='warning')
    else:
        form = UserLoginForm()
    return render(request, 'account/login.html', {'form': form})

@login_required
def dashboard(request, user_id):
    users = get_object_or_404(User, id=user_id)
    posts = Post.objects.filter(user=users)
    context = {'user': users, 'posts': posts}
    return render(request, 'account/dashboard.html', context=context)

Settings:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DEBUG = True

ALLOWED_HOSTS = []

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Post.apps.PostConfig',
    'Account.apps.AccountsConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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 = 'SocialNetworkP.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'SocialNetworkP.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = '/static/'
LOGIN_URL = 'account:user_login'

Account URL:

app_name = 'account'

urlpatterns = [
    path('login/', user_login, name='user_login'),
    path('register/', register, name='user_register'),
    path('logout/', user_logout, name='user_logout'),
    path('dashboard/<int:user_id>/', dashboard, name='user_dashboard'),
]

Main URL:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('Post.urls', namespace='post')),
    path('account/', include('Account.urls', namespace='account')),
]

Login View:

{% extends 'base.html' %}

{% block content %}
    <form action="." method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Login" class="btn btn-primary">
    </form>
{% endblock content %}

Image:

在此处输入图片说明

As you see, The next query is there in GET request but when the form is submitted URL queries are not being passed. You can see that in the image corresponding to POST request. You may need to add the next url to the login form and access the next url from POST data.

Add a hidden field in your login form

{% extends 'base.html' %} 
{% block content %} 
<form action="." method="post"> 
    {% csrf_token %} 
    {{ form.as_p }} 
    <input type="hidden" name="next" value="{{ request.GET.next }}" />
    <input type="submit" value="Login" class="btn btn-primary"> 
</form> 
{% endblock content %}

{{ request.GET.next }} is accessible by the request template context processors which is already there in the settings.TEMPLATES

And in your user_login access the next url from request.POST

def user_login(request): 
    if request.method == 'POST':
        next_url = request.POST.get('next')
        # code

Might be useful for you .

def signin(request):
    if request.method == "POST":
        user_login_form = UserLoginForm(request.POST)
        email = request.POST['email']
        password = request.POST['password']
        user = authenticate(request, email=email, password=password)
        if user and user.is_active:
            login(request, user)
            try:
                if request.GET['next']:
                    return redirect(request.GET['next'])
            except Exception as e:
                return redirect('home')
        else:
            messages.error(request, "Please Enter Correct Credential")
            return render(request, 'signin.html', context={'form': user_login_form})
    else:
        user_login_form = UserLoginForm()
        return render(request, 'signin.html', context={'form': user_login_form})

I did this way

def mylogin(request):
   #do login
   if request.user.is_authenticated:
      if request.GET.__contains__('next'): return redirect(request.GET.__getitem__('next'))
      return redirect('index')

 @login_required(login_url="/user/login")
 def view(request):
   ##restricted area

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM