Sending context with request, and {% if %} not working properly - django

I have a problem trying to figure out why below will render an html page showing 'hi' and 1, instead of just 1.
views method.
def index(request):
context = {
'test' : 1,
}
return render(request, 'index.html', context)
template html. Rendering index.html will show both 'hi' and 1. But there's no user in context, so why is the if user going through?
{% if user %}
<h1>hi</h1>
{% endif %}
{% if test %}
<h1>{{ test }}</h1>
{% endif %}

The answer is Django's builtin context processor called django.contrib.auth.context_processors.auth. It is enabled by default which means an auth.User object representing the currently logged-in user is sent to all templates with the name user automatically.
From docs:
The context_processors option is a list of callables – called context processors – that take a request object as their argument and return a dictionary of items to be merged into the context.
In the default generated settings file, the default template engine contains the following context processors:
[
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
]

if there is a user logged in django will create a AUTH_USER_MODEL representing the currently logged-in user. Also from the request object you can access the user model without specifying context. For example if a user is logged in you can do request.user.username and the username will appear in the template.

Related

How to display Model in each HTML template?

But create a request in each functions inside views.py I do not want.
Is it possible to output the model in each template using only one request?
I tried to use templateetags but
that so
#register.simple_tag(takes_context=True)
def header_categories(context):
return Categorie.objects.all().order_by('id')
what is like that
#register.simple_tag(takes_context=True)
def header_categories(context):
categories = Categorie.objects.all().order_by('id')
args = {}
for cat in categories:
args[cat.text] = {
'id':cat.id,
}
if cat.parent:
args[cat.text]['parent_id'] = cat.parent.id
args[cat.text]['parent_text'] = cat.parent.text
return args
Nothing works correctly
{% for cat in header_categories %}
cat.text
{% endfor %}
I tried through js
var arr = {%header_categories%}
but django changes everything
{'dresses': {'id': 19},
Before going deeper into your question, I think you should have
{% for cat in header_categories %}
{{ cat.text }}
{% endfor %}
You need to make a custom context processor (See Using RequestContext [Django docs]). What this would do is add a variable to the context for each template. Quoting the documentation:
The context_processors option is a list of callables – called
context processors – that take a request object as their argument and return a dictionary of items to be merged into the context.
In some suitable app of yours make a file named context_processors.py and add this code in it:
def header_categories(request):
return {'header_categories': Categorie.objects.all().order_by('id')}
Now in your settings in the TEMPLATES settings add this context processor to the list context_processors, so it should look like:
[
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'your_app.context_processors.header_categories',
]
Now in your templates you can simply write:
{% for cat in header_categories %}
{{ cat.text }}
{% endfor %}

How get current user in a template tag?

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

Django Context contains not defined field when using RequestContext

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.

Showing the logged-in user inside base.html (django)

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

Django request.user.username doesn't work

Hi
I've got a problem with the Django Template system. When I want to check in the template if a user is logged in with:
{% if user.is_authenticated %}
# success
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
I dont get to the success part. When I use in a view:
if not request.user.is_authenticated():
return render_to_response('index.html', {'inhalt': 'Not loggged in'})
else:
return render_to_response('index.html', {'inhalt': 'Succesfully loged in'})
it shows me correctly the else part.
Hope somebody can help me.
Thanks Phil
There is an example of handling the context in part 4 of the Django tutorial. However, in short...
The best way to do this is with Django's auth context proccessor. Make sure you still have it in your settings. You then need to use RequestContext
This will essentially change your code to this.
from django.template import RequestContext
# ...
return render_to_response('index.html', {
'inhalt': 'Succesfully loged in'
}, RequestContext(request))
Remember to add 'django.core.context_processors.request' to your TEMPLATE_CONTEXT_PROCESSORS in your settings.py
Example:
# Context processors
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages',
)
And add RequestContext(request):
# import
from django.template import RequestContext
# render
if not request.user.is_authenticated():
return render_to_response('index.html', {'inhalt': 'Not loggged in'})
else:
return render_to_response('index.html', {'inhalt': 'Succesfully logged in'}, RequestContext(request))
In your python you retrieve the user object that is logged in. I.e define a function get_current_user.
so your response would look something like:
class Index(webapp.RequestHandler):
def get(self):
user= get_current_user()
templates.render(self, 'mypage.html', user=user)
Then on your django template you can simply go like:
{% if user %}
<p>Hallo user {{user.name}}</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
You need to make sure that either you pass 'request.user' into the renderer. Or better yet use context based rendering:
return render_to_response('index.html',
my_data_dictionary,
context_instance=RequestContext(request))
The context_instance will use the auth middleware context processor to set the 'user' in your view.
Did you pass in your "user" instance from the view to the template? You need to make sure it is in the same context you pass into the render_to_response(), or whichever rendering method you choose for rendering the view context into the template.