I have a site which I am using user authentication to limit access to.
I am using django-allauth to handle social media authentication, but want to limit access to staff accounts only (set in the django admin panel).
I want to use a template as a header (bootstrap, nav bar etc.) with the main content loaded afterwards, or a message asking the user to login or request to be verified by admins.
My header template file: inventory/header.html
<body>
{% load bootstrap3 %}
{% if user.is_authenticated %}
{% if user.is_staff%}
{% block main %}{% endblock %}
{% block scripts %}{% endblock %}
{% else %}
<h1>Please ask an administrator to activate your account</h1>
{% endif %}
{% else %}
<h1>Please login to see this page</h1>
{% endif %}
</body>
And another template called by the view: inventory/home.html
{% include "inventory/header.html" %}
{% block main %}
This is the home page.
{% endblock %}
The view:
def home(request):
return render(request,'inventory/home.html')
Whenever I call the view, regardless of whether the user is logged in or a staff member, the main block is always displayed. The other error messages are displayed correctly.
I'm trying to avoid inserting is_authenticated/is_staff into all of my templates. I have also thought about using the login_required view decorator but that does not solve my is_staff issue.
Turns out I should have used
{% extends "inventory/header.html" %}
instead of
{% include "inventory/header.html" %}
Doh!
Related
When someone clicks on my site's logout link, I want them to be redirected to the login page but I want a message to pop up saying that they were successfully logged out. However, I don't want this behaviour to occur when someone normally visits the login page.
I decided to pass in a query string so now when someone hits logout they are redirected to users/login/?logout. How can I check for this in my template though? I want to do something like:
{% if ______ %}
*Message box appears*
{% endif %}
Thanks!
Well, you can simply use the built-in Django messaging feature!
Here's a simple example:
# views.py
from django.contrib import messages
def register(request):
# Logic
# ...
messages.success(request, 'Registered successfully!')
# ...
# More logic
-
# example.html
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">
{{ message|safe }}
X
</li>
{% endfor %}
</ul>
{% endif %}
There's a more in-depth documentation available on Django's official docs website: https://docs.djangoproject.com/en/1.11/ref/contrib/messages/
Referring to this document, I believe what you are looking for is this
{% if not request.user.is_authenticated %}
<p>You are logged out!</p>
{% endif %}
In my app I'm using the django-photologue (3rd-part app) and in its default configuration, the "View on site" admin button point to its template.
I've read that the "View on site" button use get_absolute_url() model function to implement its behavior.
I need to change the url behind "View on site" button.
Do I need to override get_absolute_url() or edit other things??
Thanks in advance.
You shouldn't change files of third-party apps if you can avoid it, because you'll essentially need to maintain a fork of the app. Instead of overriding get_absolute_url, you can override the object-tools block in the admin template. Something like this:
{% extends "admin/change_form.html" %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
{% trans "History" %}
</li>
{% if has_absolute_url %}<li>{% trans "View on site" %}</li>{% endif%}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
Save this as templates/admin/photologue/<modelnamehere>/change_form.html (change <modelnamehere> to the model you want to customize)
In a future version of Django (1.7 I guess), you will be able to override the method view_on_site to do the same thing.
Overriding get_absolute_URL() is proposed in the Django docs so it should be good to go.
See: Other model instance methods
i want to use loged in user information in my base template
{% if request.user.username %}
Logout
{% else %}
Login
{% endif %}
from django.template import RequestContext
def top(request):
return render_to_response('top.html',{}, context_instance=RequestContext(request))
If you're just wanting to check if they're logged in to display the login or logout links, I would use is_authenticated instead
{% if user.is_authenticated %}
Logout
{% else %}
Login
{% endif %}
If you are wanting to use information from the user, you can use the variables in the user class {{ user.username }}
{% if user.is_authenticated %}
Hi, {{ user.first_name }}, Logout
{% else %}
Login
{% endif %}
I use code with this structure in my base.html and it works well. I don't have anything in the template_content_processor - it works in the template on its own.
I have a site with some ajax pages. If user types in a browser /login/, he should get a full rendered template, extended from a base template. But if user clicks a login button, $('#content').ajax('/login/'); called, so i don't need to render a full template.
I.e. i have this (login_ajax.html):
{% load i18n %}
{% block title %}
{% trans "Login" %}
{% endblock %}
{% block content %}
{% include "social.html" %}
{% endblock %}
In login.html:
{% extends "base.html" %}
{% block ajax_content %}
{% include "login_ajax.html" %}
{% endblock %}
Simple login view:
def login(request):
c = Context({'user': request.user})
if request.is_ajax():
return render_to_response('login_ajax.html', c, context_instance=RequestContext(request))
return render_to_response('login.html', c, context_instance=RequestContext(request))
This problem refers to documentation of include tag:
The include tag should be considered as an implementation of “render
this subtemplate and include the HTML”, not as “parse this subtemplate
and include its contents as if it were part of the parent”. This means
that there is no shared state between included templates – each
include is a completely independent rendering process.
But i don't want to place title name in a view, or place it twice in login.html and login_ajax.html also.
I think you need to move {% block title %} back out into login.html then make two ajax calls. One to override {% block ajax_content %} and one to override {% block title %}. You could use the same pattern for overriding {% block title %} as you've used for overriding {% block ajax_content %}, but you'd probably manage without actually creating a new title.html template.
I can't see any other way round your problem.
Ok, i've found a simple solution. In fact, the problem is in question: "to extend from base, or not to extend".
In fact, i don't care a template from what login.html should be extended. So, for ajax request, the parent template will be empty.html, and for default request, it will be base.html. So, i'll point a parent template in the view:
def login(request):
c = Context({'user': request.user, 'extends': 'empty.html'})
if request.is_ajax():
return render_to_response('login.html', c, context_instance=RequestContext(request))
c['extends'] = 'base.html'
return render_to_response('login.html', c, context_instance=RequestContext(request))
The empty.html just contain a placeholder for a block:
{% block content %}{% endblock %}
And here is login.html:
{% extends extends %}
{% load i18n %}
{% if extends != 'empty.html' %}
{% block title %}{% trans "Login" %}{% endblock %}
{% else %}
<div style="display: none;" class="ajax-title">{% trans "Login" %}</div>
{% endif %}
{% block content %}
{% include "social.html" %}
{% endblock %}
Also, i suppose, there is a way to turn login.html into a snippet, that could be included using with. i.e. {% include 'snippet.html' with extends='base.html' %}
i'm developing a small app with Python and Google app engine. I'm using boilerplate (https://github.com/coto/gae-boilerplate) as front-end which follows gae direction and python templates, so nothing diffrent than plain stuff.
Now, what i would like to have is this.
When a user logged in, if the field of name and last name are not filled in i would like to have, in the home page, the profile editing.
The page for editing the profile is a template (which extend the base.html), called edit_profile.html which works well.
The homepage is a template as well (extend the base.html) called home.html.
Now, can i include the edit_profile.html in home.html? how can i do it?
this is what i've, i don't know what to put instead of ???? i tried with
{% block edit_profile.html %} {% endblock %}
but does not work
{% if user_info.name and user_info.last_name %}
..
{% else %}
????
{% endif %}
thanks.
So you want to include only some block of given template. There are two solutions:
1) Create template just for profile editing form and include it into edit_profile.html. Then include it also into home.html to if condition branch:
profile_form.html:
<form action="{% url some-action %}">
{{ form }}
<input type="submit" value="save"/>
</form
profile_edit.html
{% extends "base.html" %}
{% block main %}
{% include "profile_form.html" %}
{% endblock %}
home.html
{% if user_info.name and user_info.last_name %}
{% include "profile_form.html" %}
{% endif %}
2) use variable for extended template:
profile_form.html
{% extend BASE_TEMPLATE %}
and set it into context w/ different value as needed:
in home.html (let's say included_form.html is some basic template)
{% if user_info.name and user_info.last_name %}
{% with "included_form.html" as BASE_TEMPLATE %}
{% include "edit_profile.html" %}
{% endwith %}
{% endif %}
and if you want show form as a standalone page, set BASE_TEMPLATE to base.html