Reputation: 3920
Django always show the same page when you go to 127.0.0.1:8000/admin/logout
, whether you were logged-in before or not.
What I want is showing a Logout Successful Message only if the user was authenticated before; and show an error message if the user wasn't authenticated and try logging out.
I also need to include the user's first_name in my logout successful message.
I am using class-based django.contrib.auth.views.LogoutView
view like this:
class SignoutView(LogoutView):
template_name = "users/signout.html"
def get_next_url(self):
redirect_to = self.request.GET.get("next", "/")
return redirect_to
and here is the template:
{% extends "base.html" %}
{% block content %}
<h1>Sign out Page</h1>
<br>
{% if was_authenticated %}
<div class="alert alert-success" role="alert">
<h4 class="alert-heading">You have logged out from your account {{first_name|capfirst}}!</h4>
<p>Thanks for spending some quality time with my web site today.</p>
<hr>
<p class="mb-0" id="displayTimer"></p>
</div>
{% else %}
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">Ooh no!</h4>
<p>Looks like you are not logged in! So you can not log out! Cool yeah?</p>
</div>
{% endif %}
{% endblock %}
{% block js %}
{% if was_authenticated %}
<script type="text/javascript">
var count = 5;
var url = "{{redirect_address}}";
var countdown = setInterval(function() {
$('#displayTimer').text("You will be redirected to the home page in " + count-- + " seconds...");
if (count < 0) {
$('#displayTimer').text("Redirecting....");
clearInterval(countdown);
$(location).attr("href", url);
}
}, 1000);
</script>
{% endif %}
{% endblock %}
I adding extra content to the view like this:
class SignoutView(LogoutView):
template_name = "users/signout.html"
def set_extra_context(self):
return {
'was_authenticated': self.request.user.is_authenticated,
'first_name': self.request.user.first_name,
}
def get_next_url(self):
redirect_to = self.request.GET.get("next", "/")
return redirect_to
but it seems like the function will run after the logout process, so was_authenticated
will always be False and first_name
always None.
I know how to handle this situation with function-based views, but I rather prefer using class-based views (if possible here!).
Thanks in advance.
Upvotes: 0
Views: 3778
Reputation: 662
In python (>= 3.6) script: Override dispatch
method like bellow and add success message
from django.contrib import messages
class SignoutView(LogoutView):
template_name = "users/signout.html"
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
messages.success(request, f'{request.user.first_name} successfully logged out')
else:
messages.error(request, f'{request.user.first_name} your error message')
return super().dispatch(request, *args, **kwargs)
In template:
{% if messages %}
{% for message in messages %}
<div class="alert temp-alert {% if message.tags %}alert-{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}danger{% else %}{{ message.tags }}{% endif %}{% endif %}" role="alert">{{ message }}</div>
{% endfor %}
{% endif %}
Upvotes: 0
Reputation: 12869
Logging the user out is the very first action in the dispatch
method. So to capture data from that user, like first name, you'd have to override this method and capture that data before calling logout.
You could do something like;
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
self.first_name = request.user.first_name
return super().dispatch(request, *args, **kwargs)
The line in the source for reference; https://github.com/django/django/blob/master/django/contrib/auth/views.py#L116
Upvotes: 1