Hi I'm writing a django project, and I write template code like this:
<ul id="nav">
<li>Home</li>
<li>Users</li>
{% if user %}
<li>Settings</li>
<li>Log Out</li>
{% else %}
<li>Log In</li>
<li>Sign Up</li>
{% endif %}
</ul>
Now in login view I write like this:
def login(request):
if user_logged_in(request):
return redirect('/')
if request.method == 'GET':
form = LogInForm()
return render_to_response(LOGIN_PATH, {'form':form}, context_instance=RequestContext(request))
But when I run the server, no user is logged in, and visit login page, it shows Settings and Log Out(there is a user object in context), but it shouldn't!
If I remove RequestContext, say return render_to_response(LOGIN_PATH, {'form':form}), it will be OK. And
return render_to_response(LOGIN_PATH, {'form':form, 'user':None}, context_instance=RequestContext(request))
is OK too. But I don't want to do it.
I know it's dirty design, well... I'm looking for suggestions and solutions. Many thanks~!
{% if user.is_authenticated %}
your tag just checks for a user object, not for an authenticated one.
check here for more informations on what you can do with an auth user :)
The default setting for TEMPLATE_CONTEXT_PROCESSORS includes "django.contrib.auth.context_processors.auth". This context processor adds a user to cotnext, which will be anonymous if the user is not provided in request so.
If you want to be able to know whether or not the user is authenticated in template the #Samuele Mattiuzzo answer is what you should use, but if you don't want, for any reason, to include the user in context, then you need to modify the default TEMPLATE_CONTEXT_PROCESSORS setting without the auth context processor.
For more information read the docs or the code.
Related
How can i get the current user in a django template tags? (request object is not accessible)
Or how can i access to request object?
If you want to access the current user in a template tag, you must pass it as a parameter in the templates, like so:
{% my_template_tag user %}
Then make sure your template tag accepts this extra parameter. Check out the documentation on this topic. You should also check out simple tags.
The user is always attached to the request, in your templates you can do the following:
{% if user.is_authenticated %}
{% endif %}
You don't have to specify "request" to access its content
UPDATE:
Be aware: is_authenticated() always return True for logged user (User objects), but returns False for AnonymousUser (guest users). Read here: https://docs.djangoproject.com/en/1.7/ref/contrib/auth/
This question was already answered here:
{% if user.is_authenticated %}
<p> Welcome '{{ user.username }}'</p>
{% else %}
Login
{% endif %}
and make sure you have the request template context processor installed in your settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.request',
...
)
Note:
Use request.user.get_username() in views & user.get_username in
templates. Preferred over referring username attribute directly.
Source
This template context variable is available if a RequestContext is used.
django.contrib.auth.context_processors.auth is enabled by default & contains the variable user
You do NOT need to enable django.core.context_processors.request template context processor.
Source : https://docs.djangoproject.com/en/dev/topics/auth/default/#authentication-data-in-templates
Suppose you have a profile page of every registered user, and you only want to show the edit link to the owner of the profile page (i.e., if the current user is accessing his/her profile page, the user can see the edit button, but the user can't see the edit button on other user's profile page.
In your html file:
<h2>Profile of {{ object.username }}</h2>
{% if object.username == user.username %}
Edit
{% endif %}
Then your urls.py file should contain:
from django.urls import path
from .views import ProfileUpdateView
urlpatterns = [
...
path('<int:pk>/profile/update', ProfileUpdateView.as_view(), name = 'profile_update'),
...
]
considering you have appropriate ProfileUpdateView and appropriate model
Is there a way to access the logged in user's firstname inside the base.html file?
I'm trying to do this, because i want to display who is currently logged in on the navigation bar, but it won't access the user's information, nor will it correctly check if the user is authenticated.
html inside base.html
Hi there,
{% if user.is_authenticated %}
{{user.first_name}}
{% else %}
Stranger
{% endif %}
request.user gives you the user object that is currently logged in. So you have full access to all the attributes and methods the User class has. To get the first_name, you can do {{ request.user.first_name }}. To get the full name you use {{ request.user.get_full_name }}.
If you use [RequestContext][1], by default you get user instance in your templates so you can use it as for its attributes as {{user.first_name}} and others. The user will be same a currently authenticated user which is also available in request.user in the views.
The RequestContext by default adds some default template contexts defined in TEMPLATE_CONTEXT_PROCESSORS in your settings.py.
In your view, you can use it as
#your view code
....
#send response by rendering the template and use Requestcontext while rendering template
return render_to_response('polls/detail.html', {'poll': p},
context_instance=RequestContext(request))
Reference - Django Tutorial 04
In my website, I want to let the admins reset the password of any user.
With reset I mean exactly what the password_reset view does (under contrib.auth): Send a confirmation link to that user email.
How would be the best way of doing that? Is there an already app/snippet that does that?
Edit:
Let's suppose user john is an admin. What I want is to let john reset any user's password through the admin interface. For example, to reset max password, he will just go to the max user, and click on any link to reset his password.
What I finally did was to add a custom ModelAdmin:
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
...
def reset_password(self, request, user_id):
if not self.has_change_permission(request):
raise PermissionDenied
user = get_object_or_404(self.model, pk=user_id)
form = PasswordResetForm(data={'email': user.email})
form.is_valid()
form.save(email_template_name='my_template.html')
return HttpResponseRedirect('..')
def get_urls(self):
urls = super(UserAdmin, self).get_urls()
my_urls = patterns('',
(r'^(\d+)/reset-password/$',
self.admin_site.admin_view(self.reset_password)
),
)
return my_urls + urls
and I also had to override the change_form.html template, like this:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{# You can also give a name to that pattern and refer to it below using 'url' #}
<li>Reset password</li>
<li>{% trans "History" %}</li>
{% if has_absolute_url %}
<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
{% trans "View on site" %}</a>
</li>
{% endif%}
</ul>
{% endif %}{% endif %}
{% endblock %}
The result looks like this:
If you want a more detailed explanation, I blogged about it.
The passreset app just exposes the django views via urls.py, and adjusts the login template to show a "Forgot my password" link.
The built-in django password reset views and templates are meant for self-reset. I guess the reset form could be prepopulated with a different user's email address (in the query string) but you'd still need to make adjustments such as changing the email template - "You're receiving this e-mail because you requested a password reset for your user account" is probably not what you want:
https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/templates/registration/password_reset_email.html
Therefore you should expose the views at different URLs if you want to include self-reset as well.
Hook the django views into urls.py like so:
urlpatterns += patterns('django.contrib.auth.views',
url(r'^accounts/password/reset/$',
'password_reset',
name='password-reset'),
url(r'^accounts/password/reset/done/$',
'password_reset_done',
name='password-reset-done'),
url(r'^accounts/password/reset/confirm/(?P<uidb36>[-\w]+)/(?P<token>[-\w]+)/$',
'password_reset_confirm',
name='password-reset-confirm'),
url(r'^accounts/password/reset/complete/$',
'views.password_reset_complete',
name='password-reset-complete')
)
and where you want to make adjustments, pass in e.g. your own email template:
url(r'^/accounts/password/reset/$',
'password_reset',
{'email_template_name': 'my_templates/password_reset_email.html'}
name='password-reset'),
The "password_reset" view has more parameters you can tweak:
https://docs.djangoproject.com/en/dev/topics/auth/#module-django.contrib.auth.views
("post_reset_redirect" comes to mind as another one for your purposes)
To show a corresponding link you'd either change the User admin (careful, already registered - unregister then register your own, subclassed plus additional link field) or the change_form template itself.
I'm unaware of an app that provides this out-of-the-box, so I upvoted the question :-).
Yep, there is an app for that. Check here:
https://github.com/bendavis78/django-passreset
I have project in Django 1.3. In order to show username in all pages I use such tags in base.html
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}.
loggout</p>
{% else %}
loggin
{% endif %}
But if I dont return context_instance=RequestContext(request) from view value of user in template is empty. The 'django.contrib.auth.context_processors.auth' is included to TEMPLATE_CONTEXT_PROCESSORS.
Is it possible automaticaly include user to all templates?
since django 1.3. use shortcuts.render function and dont warry about requestcontext including to your views
You've given the answer yourself. As long as you use a RequestContext, it will be included in all templates.
If you really find that too much work, you could use the (new in 1.3) TemplateResponse class.
Or simply create a context processor. See
http://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors
Put this in context_processor.py
def root_categories(request):
return {
'user': request.user,
}
in settings.py add the context processor.
now in your template try: {{ user }}
In my template, I have the following:
<ul class="tabbed" id="network-tabs">
{% if user.is_authenticated %}
<li>My Account</li>
<li>Log Out</li>
{% else %}
<li>Log in</li>
<li>Register</li>
{% endif %}
</ul>
It seems to work fine, unless the page been created has a #login_required decorator, in which case the page works fine but the navigation appears as if the user is not logged in, even when they are.
You should check your view function to see where the user variable is coming from. Unless you're specifically passing user into the context from the view, that's your problem.
You do have access to request.user, though, and that will always return true in a template rendered from a view that has the #login_required decorator.
The reason I can tell you for certain that there's nothing wrong with the decorator, though, is that in the code for User and AnonymousUser (located in django.contrib.auth.models) the is_authenticated method strictly returns true for User and false for AnonymousUser. The decorator does not and cannot change that. And what that means is that your template isn't actually getting a User object where you're checking user.
To follow on from Gabriel's answer, is the user variable coming from the auth context processor? If it is, and you are using the render_to_response shortcut, you need to use a RequestContext instance.
from django.template import RequestContext
...
#login_required
def some_view(request):
# ...
return render_to_response('my_template.html',
my_data_dictionary,
context_instance=RequestContext(request))