Django NoReverseMatch when trying to logout - django

I have a django view function signout that I want to call form a form/template. When i click logout, it calls the function but the redirect after doesnt work. I get the message Reverse for '<WSGIRequest: POST '/account/signout'>' not found. '<WSGIRequest: POST '/account/signout'>' is not a valid view function or pattern name.
Urls.py
urlpatterns = [
path('register', views.register, name='register'),
path('login', views.login, name='login'),
path('signout', views.signout, name='signout'),
path('dashboard', views.dashboard, name='dashboard'),
]
Views.py
def signout(request):
if(request.method == 'POST'):
auth.logout(request)
messages.success(request, 'You are logged out!')
return redirect(request, 'index')
Template form
<form action="{% url 'signout'%}" id="logout" method="POST">
{% csrf_token %}
<input type="hidden">
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-sign-out-alt"></i>
Log Out</button>
</form>
What is going wrong?? The rest of routes work just fine and they are declared the same as signout.

You are doing wrong in your view .You don't need parenthesis while checking the if condition and redirect doesn't take the request parameter.
Change your view like this
def signout(request):
if request.method == 'POST':
auth.logout(request)
messages.success(request, 'You are logged out!')
return redirect('index')

Related

Django redirect not working in authentication

I am trying to authenticate a registered user . redirect is not working in my case. after clicking the login button it keep on showing the login page again. i want the user to go to home page upon the successful login. Here are my files.
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
def register_new_a(request):
saved = False
if request.method == "POST":
# take whatever is posted to the Details Form
form = DetailsForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your account details have been saved!')
return HttpResponseRedirect('/register_new_a?saved=True')
else:
form = DetailsForm()
if 'saved' in request.GET: # sends saved var in GET request
saved = True
return render(request, 'register1.html', {'form': form, 'saved': saved})
def loginUser(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
# at backend authenticated the credentials
login(request, user)
return redirect('home') # not working
return render(request, 'login_a.html')
urls.py
from django.contrib import admin
from django.urls import path
from home import views
urlpatterns = [
path("", views.index, name='home'),
path("login", views.loginUser, name='login'),
path("logout", views.logoutUser, name='logout'),
#path("register", views.register, name='register'),
path("register_new_a", views.register_new_a, name='register_new_a'),
path("register_new_b", views.register_new_b, name='register_new_b'),
path("about", views.about, name='about'),
]
login_a.html
{% extends 'base.html'%}
{% block title %}Login{% endblock title %}
{% block body %}
<div class="container my-3" >
<h1 class="display-3" align="center">Login Here</h1>
<br>
<h1 class="display-6" >STEP 1: </h1>
<form method="post" action="">
{% csrf_token %}
<div class="mb-3">
<label for="Username1" class="form-label" >Username </label>
<input type="username"class="form-control" name="username"></input>
</div>
<div class="mb-3">
<label for="Password1" class="form-label">Password</label>
<input type="password" class="form-control" id="Password1" name="password">
</div>
New user? Register Here
<button type="submit" class="btn btn-primary float-end" style="background: #0a9396" > Next</button>
</form>
</div>
{% endblock body %}
Any help would be appreciated.

Why is my Django login not getting authenticated?

I do know that this is a repeated question. I did refer those answers but still I couldn't get my issue fixed. Kindly do help. Registration works just fine. The registered users gets added to the DB fine. Logout works fine. The issue is with login. Whenever I try logging in , I keep getting the response "Invalid login details".
views.py
from django.shortcuts import render, redirect
from . forms import *
from django.http import HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
# USER LOGIN
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user =authenticate( username=username, password=password)
if user is not None:
if user.is_active:
login(request,user)
return redirect('home')
else:
return HttpResponse("Account not active")
else:
return HttpResponse("Invalid login details") #whenever I try to login, I always gets this response.
else:
return render(request, 'basic_app/login.html')
#USER LOGOUT
#login_required
def user_logout(request):
logout(request)
return redirect('login')
urls.py(application).
from django.urls import path
from . import views
urlpatterns = [
path('',views.index, name='home'),
path('register/',views.register, name='register'),
path('login/',views.user_login, name='login'),
path('logout/',views.user_logout, name='logout'),
]
login.html
{% extends 'basic_app/base.html' %}
{% block body_block %}
<div class='jumbotron'>
<h2>User Login</h2>
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
<label for="username">Username:</label>
<input id="username" type="text" placeholder="Enter Username">
<label for="password">Password</label>
<input id="password" type="password" placeholder="Enter Password">
<input type="submit" value="Login">
</form>
</div>
{% endblock %}
settings.py
LOGIN_URL = '/basic_app/login/'
Try this:-
Make a copy of your Project in another folder. AND delete the current database and
create a new Database as usual like :- IN Terminal - Create Superuser command is :-
python manage.py createsuperuser.
In your views.py, in the user_login function you are checking if the user.is_active.
Instead try checking if the user is authenticated in the if statement.
Because I think that the user would probably be inactive before being logged in or authenticated.
For example, this is from the documentation:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
Check the documentation here
Edit
Sorry, I was lookin at the wrong if block.
You don't seem to have assigned anything to the user variable. That maybe why the user is returned as none.
Also you can try:
user = request.user

When doing GET request to localhost:121/logout I get "accounts.views.logout didn't return an HttpResponse object". Is this an issue?

When I go to localhost:121/logout I get The view accounts.views.logout didn't return an HttpResponse object. It returned None instead.
Should I modify my code, to deal with this, or is this not an issue? My logout is working fine. Do I have to list logout in my urls.py?
views.py
def logout(request):
if request.method == "POST":
auth.logout(request)
return redirect('login')
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.register, name='register'),
path('logout', views.logout, name='logout'),
path('', views.login, name='login'),
]
profile.html
<ul>
<li>
<a class="dropdown-item" href="javascript:{document.getElementById('logout').submit()}">Logout</a>
</li>
<form id="logout" action="{% url 'logout' %}" method="POST">
{% csrf_token %}
<input type="hidden">
</form>
</ul>
GET and POST requests can be redirected the login page. The logout method is also suitable for logged out users.
def logout(request):
auth.logout(request)
return redirect('login')
It really depends on what you want your application to do. What do you want to happen when you navigate to /logout? If you want to provide your users with a way of logging out just by navigating there, then you can just deal with the GET and POST requests together. (As suggested by #Beste) e.g:
def logout(request):
auth.logout(request)
return redirect('login')
This has the additional advantage that you can logout from anywhere on the site just by using a hyperlink to this URL.
If you don't want this to happen, I would suggest raising a 405 (method not allowed), e.g:
from django.http import HttpResponse
def logout(request):
if request.method == "POST":
auth.logout(request)
return redirect('login')
return HttpResponse(status_code=405)
And yes, whatever you do you will need to list it in your urls.py somewhere. Or you could even use a HttpResponseNotAllowed (see here)

maximum recursion depth exceeded on logout(request)

I'm trying to create the logout functionality on my page. But getting this recursion error, everytime I hit the link that points to the logout url.
Below is the code, for what is suppose to be showing content and a logout functionality if the user is logged in. Otherwise show the login form.
view methods
def login(request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
context = {
}
if user is not None:
print('Correct user'
else:
print('Wrong user')
return render(request, 'index.html', context)
def logout(request):
print('logged out')
logout(request)
return redirect('index')
url
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^login/$', views.login, name='login'),
url(r'^logout/$', views.logout, name='logout'),
]
index.html
{% if user %}
<h3>Hello {{user.username}}</h3>
Logout
{% else %}
<form action="{% url 'crowd:login' %}" method='post'>
{% csrf_token %}
<input class='logintext' type='text' placeholder='Username' name='username'>
<input class='logintext' type='password' placeholder='Password' name='password'><br>
<input class='loginbutton' type='submit' value='Login'>
<a class='loginforgotpassword' href="{% url 'crowd:register' %}"> Forgot password?</a>
<a class='loginregister' href="{% url 'crowd:register' %}"> Register</a>
</form>
{% endif%}
console error:
File "C:\Users\Rasmus\workspace\Crowd\src\Cr\views.py", line 48, in logout
logout(request)
File "C:\Users\Rasmus\workspace\Crowd\src\Cr\views.py", line 48, in logout
logout(request)
File "C:\Users\Rasmus\workspace\Crowd\src\Cr\views.py", line 48, in logout
logout(request)
File "C:\Users\Rasmus\workspace\Crowd\src\Cr\views.py", line 47, in logout
print('logged out')
RecursionError: maximum recursion depth exceeded
[04/Sep/2016 23:35:59] "GET /Crowd/logout/ HTTP/1.1" 500 3210436
Kindly change name of your logout view.
The error is with:
def logout(request):
print('logged out')
logout(request)
return redirect('index')
your view name is logout with request parameter. so when you call logout(request) in the view, it calls your logout view not Django's logout function. that's causing recursion.

Django Redirect the Logout Process to a View

I am very new to django, I have a following template:
{% if settings.LOGIN_SYSTEM %}
{% trans %}sign out{% endtrans %}
{% endif %}
I also have a view that clears out all the session:
class LogoutView(TemplateView):
redirect_field_name = "target"
def get(self, *args, **kwargs):
I want to make sure the login signal goes through the LogoutView get method. Can I call a view method from template?
If so an example would be great.
To logout use POST instead of GET. It is a architecture issue.
So to logout you should make a post request like the following example.
Logout template form
<form action="{% url 'logout' %}" method="post" >
{% csrf_token %}
<input type="submit" value="Logout" />
</form>
Logout url
urlpatterns = patterns('',
url(r'^logout/$', LogoutView.as_view(), name='logout'),
# other urls...
)
Logout view
from django.contrib.auth import logout
class LogoutView(ProcessFormView):
def post(self, request, *args, **kwargs):
logout(request)
return redirect('login-url-name')
Example logout
#require_POST
def logout(request):
auth.logout(request)
return redirect('/')