User Authentication based on if logged in or not django - django

I have an issue with my application I'm building. I understand how to validate if a user in django is logged in or not and whether their session is active with:
if user is not None and user.is_active:
My issue is my django templates specifically with the section with Register | Login that look like:
<div id="subnav_registrationLogin">
<ul>
{% block block_containersupernav %}
<li><span>Register</span></li>
<li style="border:none;"><span>Login</span></li>
{% endblock block_containersupernav %}
</ul>
</div><!-- /subnav_registrationLogin -->
The issue is, my template is static and for this little code snippet above needs be more dynamic like:
if user is not None and user.is_active:
Log Out
elif:
<div id="subnav_registrationLogin">
<ul>
{% block block_containersupernav %}
<li><span>Register</span></li>
<li style="border:none;"><span>Login</span></li>
{% endblock block_containersupernav %}
</ul>
</div><!-- /subnav_registrationLogin -->
How can I achieve this within a template? and if I cannot within a template, how should I be doing this? Thank you!

Templates are rendered based on the context. So try this:
{% if user.is_authenticated %}
Logout
{% else %}
<div id="subnav_registrationLogin">
<ul>
{% block block_containersupernav %}
<li><span>Register</span></li>
<li style="border:none;"><span>Login</span></li>
{% endblock block_containersupernav %}
</ul>
</div>
{% endif %}
is_authenticated() is a helper method in the django.contrib.auth.user model
Also, note that is_active flag is used to check if the user is active or not, and should be used to check if the user can be successfully logged into the system or not.
You could also access the current logged in user using request.user.is_authenticated in the template.

So something like this?
{% if user.is_authenticated %}
<li>Logout</li>
{% else %}
<div id="subnav_registrationLogin">
<ul>
{% block block_containersupernav %}
<li><span>Register</span></li>
<li style="border:none;"><span>Login</span></li>
{% endblock block_containersupernav %}
</ul>
</div><!-- /subnav_registrationLogin -->
{% endif %}

Related

django-allauth or django in general render template on user status

My menu in the html looks like this:
<ul id="nav-mobile" class="right">
{% user_display user %}
<li>Login</li>
<li>Logout</li>
<li>Signup</li>
</ul>
Obivous this doesn't make much sense, cause if a user is not logged in it should be possible to logout and vice versa.
Are there any template-tags in django or django-allauth, which I can write in the template like. PseudoCode
<if user login>
<a> logout </a>
<end if>
You can simply check if user is logged in with is_authenticated in your template like this:
{% if request.user.is_authenticated %}
{% user_display user %}
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Signup</li>
{% endif %}

django tables how to detect if table is empty

I am new to django and web development and based on examples and help on SO, I have pieced together something which takes a model and renders it in a django-table. My template code is basically as follows:
{% block content %}
{% load static %}
{% load render_table from django_tables2 %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% endblock %}
The view is as follows:
#login_required(login_url="login/")
def review(request):
table = DummyTable(DummyModel.objects.all())
form = DummyForm()
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'review.html', {'reviews': table, 'DummyForm': form})
This works fine. However, what I would like to do is show a message to the user saying that there are no records when the database table is empty. In the current setting, it shows an empty table with the columns which is probably not the best from a usability point of view.
There are two options. Either you set empty_text inside class Meta
class Reviews(tables.Table):
class Meta:
empty_text = _("There are no reviews yet")
Or you can check it inside the template and avoid rendering table this way
{% if reviews_table.data.list %}
{% render_table reviews_table %}
{% else %}
<h1>There are no reviews yet</h1>
{% endif %}
Probably the easiest way is in your template. Assuming your variable that's empty is called reviews:
{% block content %}
{% load static %}
{% if reviews %}
{% load render_table from django_tables2 %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% else %}
<span> Whatever holding response/error message you want. </span>
{% endif %}
{% endblock %}
Per this this answer, for example, using {% if variable %} against a valid but empty variable, it generally evaluates to False, letting you use the {% if reviews %}.
However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.
You could also do it in your views, and pass an error message back to the template using the standard Messages framework included in Django:
from django.contrib import messages
messages.add_message(request, messages.INFO, "No reviews found, I'm afraid!.")
You need to include something like this in your templates to use messages:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
Or you could do both! :)
test against table.paginated_rows it will be empty and evaluated to False when the table have no data.
they use this in django_tables2/templates/django_tables2/bootstrap.html:~26 template:
{% for row in table.paginated_rows %}
...
{% empty %}
... {{ table.empty_text }}
{% endfor %}
Do this:
{% if reviews %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% else %}
<div>
<p> Message to use </p>
</div>
{% endif %}
Milano answer worked to me, but removing ".list" from the if conditional:
{% if reviews_table.data.list %}
{% render_table reviews_table %}
{% else %}
<h1>There are no reviews yet</h1>
{% endif %}

extend other app to my template working

I want to extend an other template to my blog.html, no matter have i try to extend this, it doesn`t work .
blog/index.html
{% block nav %}
<ul id="nav">
<li>{% block nav-blog %}Blog{% endblock %}</li>
<li>{% block nav-photo %}Photo{% endblock %}</li>
</ul>
{% endblock %}
<div class="news">
{% block polls %}
{% extends 'polls/index.html' %}
{% endblock %}
<div>
polls/index.html
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Usually extends has to be stuck at the top of the template and not somewhere in the template.
In the template you use the tags that you have set up in the base templates.
You need to make sure you're doing two things here:
Declare a "nav" block in your index.html. This will let django know the part of your index html you wish to have overwritten when a template extends it. Anything you put inside the "nav" block in index html will be considered default content.
You need to use the "extends" template tag at the beginning of your blog.html so django knows the template you'd like to extend.
Like this:
index.html
{% block nav %}
<div>
Some default html here..
</div>
{% endblock %}
And then blog.html
{% extends index.html %}
{% block nav %}
<div>
This is what will render
</div>
{% endblock %}
Also, you're going to want to test index.html before trying to extend it to verify that django is finding that template. If it isn't then you need to add the directory that it is found in to the TEMPLATE_DIRS array in your settings.py file.

Django authentication acting weird. Working "some times", not always

I'm having some trouble with Django's authentication system. I've managed to set up a login page, logout page and a basic profile page. Now I'm trying to restrict different areas on the site to only authenticated users. It works on some templates, and not on others.
The weirdest, maybe, is that it works/not works in the same template.
This is base.html:
<div id="account">
{% if user.is_authenticated %}
Hello, {{ user.username }}! | Log out
{% else %}
Log in
or
Sign up
{% endif %}
</div>
<div id="sidebar">
{% if user.is_authenticated %}
<h3 id="plus" style="padding-top: 20px;">Sign up!</h3>
Log in
{% else %}
<div style="margin-top: 45px">
Profile
</div>
{% endif %}
</div>
Works in the account-div, but not in the sidebar-div.
Any suggestions?
You have
{% if user.is_authenticated %}
<h3 id="plus" style="padding-top: 20px;">Sign up!</h3>
Log in
{% else %}
why does he have to sign up if he's logged in?
You can try {% if not user.is_authenticated %}

Django template conditional variable assignment

I want to assign a variable do different values depending on if a variable exists, is this possible? My non working example might make it clearer:
{% if username %}
{% with menu_user=username %}
{% elif recent_users %}
{% with sorted_users=recent_users|dictsortreversed:"timestamp" %}
{% with menu_user=sorted_users.0.username %}
{% endif %}
{% if menu_user %}
<div id="menu">
<ul>
<li>Profile</li>
<li>Products</li>
</ul>
</div>
{% endif %}
{% if recent_users %}
{% endwith %}
{% endif %}
{% endwith %}
Pseudocode of what I try to do:
if username:
menu_user = username
elif recent_users:
menu_user = sorted(recent_users)[0]['username']
if menu_user:
<div id="menu">
<ul>
<li>Profile</li>
<li>Products</li>
</ul>
</div>
update
Then its better to customize a template tag like
#register.inclusion_tag('menu_snippet.html') # or you could use takes_context=True and fetch values from the context
def render_menu(username, recent_users):
if username:
menu_user = username
elif recent_users:
# sorted here could be replaced by min or QuerySet method, it depends
# for example:
# menu_user = min(recent_users, key=lambda u:u.timestamp).username
menu_user = sorted(recent_users)[0]['username']
return {'menu_user':menu_user}
# in template, it looks like
{% render_menu username recent_users %}
Putting the code in the view is much better. Just as your pseudocode, clean and readable.
If you still want to write template, I prefer something like
{% if username %}
<div id="menu">
<ul>
<li>Profile</li>
<li>Products</li>
</ul>
</div>
{% else %}
{% if recent_users %}
{% with sorted_users=recent_users|dictsortreversed:"timestamp" %}
{% with menu_user=sorted_users.0.username %}
<div id="menu">
<ul>
<li>Profile</li>
<li>Products</li>
</ul>
</div>
{% endwith %}{% endwith %}
{% endif %}
{% endif %}
Depends on your actual usage, customized template tag or the include tag are also possibly useful.
Template tag:
#register.assignment_tag
def alias(obj):
"""
Alias Tag
"""
return obj
Template:
{% alias sorted_users.0.username as menu_user %}
Create a template tag that takes username and recent_users as arguments which then outputs the menu. That way you will keep your template clean from that kind of logic.