简体   繁体   中英

Django unable to render logout template

Have the following problem; I am following Django by Example, Antonio Mele.The exercise here, is to set up user login and logout.Using the default contrib.auth views. When the code in the book is used. The logout view is that of the admin page logout; seems to be same issue as described here

django logout redirects me to administration page . Have tried all there no success

I have been working on this problem. My code now works, in that the admin template is no longer rendered. However, I am still unable to use my own logout.html. I can redirect to my own login.html... but not the logout.html.The logging out itself is working. User can log in, and out only this issue with the templates. I now only receive one browser error

The page isn't redirecting properly Iceweasel has detected that the >server is redirecting the request for this address in a way that will >never complete.This problem can sometimes be caused by disabling or >refusing to accept cookies.

checked the cookies can see csrf token is accepted

no traceback available no errors :-(

If I use the code below , all works with one exception. I am redirected at logout to the Django Administration logout template, and not my own logout.html....This is when using coede in the book.... My own modified code, with a seperate logout function also did not work generating a maximum recurson error.Editing the URLS.PY stops the rendering of the admin template. but the modified code seems to have an issue in the urls ie .....

THIS IS NOT WORKING !!!!!

 url(r'^logout/$', 'django.contrib.auth.views.logout',{'next_page': '/account/logout'},  name='logout'),

THIS WORKS PERFECTLY !!!!

 url(r'^logout/$', 'django.contrib.auth.views.logout',{'next_page': '/account/login'},  name='logout'),

The code from the book is as follows

FROM BOOK SETTINGS.PY

from django.core.urlresolvers import reverse_lazy

LOGIN_REDIRECT_URL = reverse_lazy('dashboard')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')

FROM BOOK VIEWS.PY

from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import LoginForm

@login_required
def dashboard(request):
    return render(request, 'account/dashboard.html', {'section': 'dashboard'})


def user_login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(username=cd['username'], password=cd['password'])
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse('Authenticated successfully')
                else:
                    return HttpResponse('Disabled account')
            else:
                return HttpResponse('Invalid login')
    else:
        form = LoginForm()
    return render(request, 'account/login.html', {'form': form})

FROM BOOK MAIN URLS.PY

from django.conf.urls import include, url
from django.contrib import admin



urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^account/', include('account.urls')),
    ]

MYAPP(account) URLS.PY

from django.conf.urls import url
from . import views


urlpatterns = [
    # url(r'^login/$', views.user_login, name='login'),
    url(r'^$', views.dashboard, name='dashboard'),



    # login / logout urls
    url(r'^login/$', 'django.contrib.auth.views.login', name='login'),
    url(r'^logout/$', 'django.contrib.auth.views.logout', name='logout'),
    url(r'^logout-then-login/$', 'django.contrib.auth.views.logout_then_login', name='logout_then_login'),

MY MODIFIFED CODE

I have now include a seperate logout definition in my view's and now also pass a {key:value} pair of {'next_page': '/account/logout'}.

if the logout def is used and mapped in the urls file it generates a maximum recursion error at line logout(request)

def logout(request):
    logout(request)
    request.session.flush()
    request.user = AnonymousUser
    # Redirect to a success page.
    return HttpResponseRedirect(request,'/account/logout.html',context_instance = RequestContext(request))

without this def the only error generated is

""" The page isn't redirecting properly

"""Iceweasel has detected that the server is redirecting the request for this address in a way that will never complete.

This problem can sometimes be caused by disabling or refusing to accept cookies.""""

""" I checked cookies in the browser, and see the csrf_token being accepted

For me the strange thing is that if the code: {'next_page': '/account/logout'} is changed to {'next_page': '/account/login'} everything works perfectly. Have tried all suggestions found, am at a loss any help appreciated ....

MY CODE VIEWS.PY

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from .forms import LoginForm
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.contrib.auth.models import User


# Create your views here.

@login_required
def dashboard(request):
    return render(request, 'account/dashboard.html',{'section': 'dashboard' })




def user_login(request):
    cd = None
    if request.method=='POST':
        form  = LoginForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(username=cd['username'],
                                password=cd['password'])
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse('Authenticated successfully')
                else:
                    return HttpResponse('Disabled Account')
            else:
                return HttpResponse('Invalid Login')
    else:
        form = LoginForm()
    return render(request, 'account/login.html',{'form': form},context_instance = RequestContext(request))


def logout(request):
    logout(request)
    request.session.flush()
    request.user = AnonymousUser
    # Redirect to a success page.
    return HttpResponseRedirect(request,'/account/logout.html',context_instance = RequestContext(request))

MY CODE account/urls.py

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



urlpatterns = [
              # post views
              #url(r'^login/$', views.user_login, name='login'),
              # login/logout urls
              url(r'^$', views.dashboard, name='dashboard'),
              url(r'^login/$', 'django.contrib.auth.views.login', name='login'),
              url(r'^logout/$', 'django.contrib.auth.views.logout',{'next_page': '/account/logout'},  name='logout'),
              url(r'^logout-then-login/$','django.contrib.auth.views.logout_then_login', name='logout_then_login'),

              ]

MY CODE MAIN URLS.PY

from django.conf.urls import include, url
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^account/', include("account.urls")),
]

MYCODE SETTINGS.PY

LOGIN_REDIRECT_URL = reverse_lazy('dashboard')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')

INSTALLED_APPS = (
    'account',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

)

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


# urlpatterns += patterns('django.contrib.auth.views',
#          #url(r'^login/$', 'login', { 'template_name': 'registration/login.html'}, name='login' ),
#          #url(r'^logout/$', 'logout', { 'template_name': 'registration/logout.html', 'next_page':reverse('index') }, name='logout' ),
#  )

MYCODE
logout.html

{% extends "base1.html" %}

{% block title %}Logged Out{% endblock %}


{% block content %}
<h1>
    Logged Out
</h1>
<p>
    You have been successfully logged out. You can <a href="{% url "login" %}">Log-in again</a>
</p>{% endblock %}

MYCODE base1.html

{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
</head>
<body>


<div id="header">
    <span class="logo">
        BookMarks
    </span>
{% if user.is_authenticated %}
<ul class="menu">

<li {% if section == "dashboard" %}class="selected"{% endif %}>
<a href="{% url 'dashboard' %}">My dashboard</a>
</li>
<li {% if section == "images" %}class="selected"{% endif %}>
<a href="#">Images</a>
</li>
<li {% if section == "people" %}class="selected"{% endif %}>
<a href="#">People</a>
</li>
</ul>
{% endif %}

{%if user.is_authenticated %}
<span class="user">


Hello {{ user.first_name }} {{ user.last_name }},
<a href="{% url 'logout'  %}">Logout</a>

{% else %}
<a href='{% url "login" %}'>Log-in</a>
{% endif %}
</span>
</div>

<div id="content">
    {% block content %}
    {% endblock %}
</div>

</body>

</html>

You are using contrib.auth 's logout view in your urls.py . This view redirects to the URL specified by 'next_page' . You provide '/account/logout' as next_page -- where again the logout view is called!

That leads to an (infinite) redirect loop : the view redirects to itself.

Try instead: in your own logout view:

# no redirecting here!
return render(request, 'account/logout.html', 
              context_instance=RequestContext(request))

Add a url for that view in account/urls.py :

url(r'^post-logout/$', logout, name='post-logout'), 
# logout being your own view

Then provide that url as 'next_page' to the actual ( auth ) logout:

url(r'^logout/$', 'django.contrib.auth.views.logout',
    {'next_page': '/account/post-logout'},  name='logout'),

The solution to the problem is to map the url as follows

url(r'^logout/$', 'django.contrib.auth.views.logout', { 'template_name': 'account/logout.html',}, name='logout' ),

I was having same issue, but then I kept reading

"If you are seeing the log out page of the Django administration site instead of your own log out page, check the INSTALLED_APPS setting of your project and make sure that django.contrib.admin comes after the account application. Both templates are located in the same relative path and the Django template loader will use the first one it finds."

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