Django - check if user is authenticated for every url - django

On my html, I can check if the user is logged in by using the following syntax:
{% if user.is_authenticated %}
<div id="display_something">...</div>
{% else %}
<p>Please Log in</p>
{% endif %}
But what should I do if I want to check if the user is authenticated for every html file I am rendering? Do I have to copy and paste that {% if ... %} block for every single html file? What is the Django's way of handling this issue? What's the good practice?

in your base.html, add your check
{% if user.is_authenticated %}
{% block page %}
{% endblock %}
{% else %}
<p>Please Log in</p>
{% endif %}
then with all your other pages, add {% extends 'base.html' %} at the top. You will need to give it a relative link to base.html.
Then the rest of your code on that page needs to sit between tags like below.
{% block page %}
<!-- all your html code here -->
{% endblock %}
Notice that after block, you need to have the same name. for this example, it is page but you can pick your own variable name.

You shouldn't handle the authentication logic in the template (for the entire site), instead you can use the login_required decorator on your views.
from django.contrib.auth.decorators import login_required
#login_required
def my_view(request):
...

Related

Using d Django Abstract Base User model to enable Profile tab

Using Django Abstract Base User model, How do I make the Profile tab show when a user is logged in. Should I create a model/form for Profile, This is the image of the html file. The backend for signup and login works perfectly fine but when a user signs up or logs in, the nav bar doesn't change at all. Please help
{% extends 'base.html' %}
{% block title %}Profile{% endblock %}
{% block content %}
<h1>Hello World</h1>
{% if user.is_authenticated %}
Profile
Logout
{% else %}
Sign Up
Log In
{% endif %}
{% endblock %}

Django: how to pass value from a list template to a view, static url

In my template, I have a list of users on which the connected user can click to access the profile of a user on the list. I want to retrieve the user I clicked on in my view. However, I would like to keep a static URL (to avoid having user-related settings displayed in the URL). Do you have any idea how to do that?
Here is my template :
{% extends "base.html" %}
{% block content %}
{% if userConnected.adminRole == "SuperUser" %}
<h2>Members List</h2>
<h3>Members from OU : {{ userConnected.ou }} </h3>
{% for element in user_list %}
<p>{{ element.first_name }}</p>
{% endfor %}
{% endif %}
{% endblock %}
What should I add to my template and what should I write in my view "edit_other_profile" to get the right user ? Thanks a lot

how to override wagtail admin login page

I am trying to build my own custom login page for wagtail admin login page. Everything is working fine I removed all the content by extending
{% extends "wagtailadmin/login.html" %}
Login is working but the default sign in button is still showing in my custom login page. How to remove it.
Here my own custom login page code is
{% extends "wagtailadmin/login.html" %}
{% load staticfiles i18n %}
{% block css %}
#Loaded my css files here
{% endblock %}
{% block branding_login %}{% endblock %} # to Remove branding login(login to wagtail site)
{% block fields %}
#Login form here
{% endblock %}
To replace the submit button, define a submit_buttons block on your template.
http://docs.wagtail.io/en/v2.1.1/advanced_topics/customisation/admin_templates.html#submit-buttons

Overriding django admin dashboard and adding logic on it

I would like to know how could I add some logic on my admin dashboard. I need to make queries on three different models and show data on Dashboard template but still can't handle the template extention with different models data.
Thanks!
Accomplishing what I was planning to do looked weird. I would need to change the base_site.html rendering view to show up these information, or something else that I don't know how to deal with, so, what i did was:
Extend admin/base.html on /templates/admin loading original data, and overriding some blocks
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}
{{ title }}
{% endblock %}
{% block branding %}
<h1 id="site-name">Administration</h1>
{% endblock %}
{% block nav-global %}
<center>
<button>Reports</button>
<button>Graphs</button>
</center>
{% endblock %}
It's working fine by now, but still don't know how to deal with admin view of base_index.html

Use django-pagination to generate link refl=next/prev

I'm using django-pagination to paginate my pages. It works great, but I would like to set up
<link rel="prev" href="http://www.example.com/foo/?page=1" />
<link rel="next" href="http://www.example.com/foo/?page=3" />
to the <head>, like it is recommended by google .
However I found no way ho to do this (without extra queries at least). First I tried to edit the pagination/templates/pagination.html with something like this
{% block extra_head %}
<link rel=... ... />
{% endblock %}
Which of course did not work (pagination.html is included by the {% paginate %} tag, it does not extend my layout.html). Next, I tried to modify my template for /foo/ view to something like this (adding the {% block extra_head %}):
{# foo.html #}
{% extends "layout.html" %}
{% block content %}
{% load pagination_tags %}
{% autopaginate object_list %}
{% paginate %}
{% for obj in object_list %}
{{ obj }}
{% endfor %}
{% paginate %}
{% endblock %}
{% block extra_head %}
<link rel="prev" href="?page={{ page_obj.previous_page_number }}"/>
{% endblock %}
But this won't work either, as the page_obj variable is only available in scope of {% block content %}. A could call
{% autopaginate object_list %}
in the extra_head block, but that will mean an extra hit to the db (and possibly other side effects that I'm not aware of). Is there an elegant way to solve this, ideally as DRY as possible?
Edit: I'm using django 1.2.
You can do {% autopaginate %} in higher-level block, then paginated objects will be available in sub-blocks. If you don't have higher level block it is possible to do this in base template:
{% block root %}
...
{% endblock %}
And in extended template:
{% extends "base.html" %}
{% load pagination_tags %}
{% block root %}
{% autopaginate objects 10 %}
{{ block.super }}
{% endblock %}
<!-- the rest of your code -->
Now, to get a different rendering of paginator in head, you can make use of the with tag:
{% with we_are_in_head=1 %}
{% paginate %}
{% endwith %}
And override templates/pagination/pagination.html with something like this:
{% if we_are_in_head %}
# Your links to next and prev only
{% else %}
# original code
{% endif %}
A moral
This is not elegant and the reason is that pagination should be implemented in the view. Templates are for rendering only, template-tags too. Pagination makes extra sql queries, it also parses arguments from request, template is totally wrong place for this code, so workarounds has to be invented. These workarounds might break on next release of django, they are also subtle and can be accidentally broken by other developer.
We can call autopaginate in a view and then use {% paginate %} as usual. Here is a recipe if somebody still face the described problem:
from pagination.templatetags.pagination_tags import AutoPaginateNode
def autopaginate(request, context, queryset_var, paginate_by):
""" It allows us to use paginated objects in different template blocks """
autopagination = AutoPaginateNode(queryset_var, paginate_by)
# Inject a request - it's required by `autopagination` function
context['request'] = request
autopagination.render(context)