Where to import stuff for a template in Django? - django

Sorry for the dumb question, I'm lost.
I got a template and a templatetags with this :
menu_tags.py
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html')
def show_menu():
buttons = Button.objects.all()
return {'buttons': buttons}
And this :
home.html
{% for button in buttons %}
{% if user.is_authenticated %}
stuff
{% endif %}
{% endfor %}
I would like to know, how can I make user.is_authenticated work ? I know I have to import something, but where ? Importing it in menu_tags does not seems to work.
Thanks !

As suggested by other users in the comments, try the following:
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html', takes_context=True)
def show_menu():
request = context['request']
if request.user.is_authenticated: # if Django 1.10+
buttons = Button.objects.all()
else:
buttons = None
return {'buttons': buttons}
And then in your template, make sure you load your new templatetags and try:
{% load menu_tags %}
{% for button in buttons %}
{{ button }}
{% endfor %}

Related

Check if text exists in Django template context variable

This may not be the best way of doing this (open to suggestions). But I want to display a button on my home page depending on the value of a Boolean in the custom user model.
I am passing the value of this boolean via context in the view. But I can't seem to get the template logic to work.
Models.py
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
isAdmin = models.BooleanField(default = False,)
#more models...
views.py
from django.views.generic import TemplateView
from django.contrib.auth import get_user_model
from accounts.models import CustomUser
class HomePageView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
adminStatus = CustomUser.objects.get(id=self.request.user.id)
print(adminStatus.isAdmin)
context['adminStatus'] = str(adminStatus.isAdmin)
return context
home page template.html
{% extends 'base.html' %}
{% block body %}
{% if user.is_authenticated %}
<h4>Hi {{ user.username }}!</h4>
<a class="btn btn-primary btn-lg" href="{% url 'dashboard' %}" role="button"> Go to Dashboard</a>
{% else %}
<p>You are not logged in</p>
login
</div>
{% if adminStatus == "True" %}
<h1>test</h1>
<div class = "adminPanel">
<a class="btn btn-primary btn-lg" href="{% url 'newEquipment' %}" role="button"> add new equipment</a>
</div>
{% endif %}
{% endif %}
{% endblock %}
I can't see the "newEquipment" button even though the adminStatus context is equal to "True", as verified by the print() command.
I have a feeling my template logic is not correct. I also tried:
{% if adminStatus contains "True" %}
In the view, context['adminStatus'] is defined only when the user is logged in. Meanwhile in the template, you are checking for adminStatus when the user is not logged in.
First the return context statement needs to be un-indented once, so that context (with or without adminStatus) is available regardless:
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
adminStatus = CustomUser.objects.get(id=self.request.user.id)
context['adminStatus'] = adminStatus.isAdmin
return context
Next, yes you probably need to fix your template logic. Assuming you want to check for adminStatus only if the user is logged in, it should look like:
{% if user.is_authenticated %}
<h4>Hi {{ user.username }}!</h4>
...
{% if adminStatus %}
<h1>test</h1>
...
{% endif %}
{% else %}
<p>You are not logged in</p>
...
{% endif %}
Original answer:
In the view, you likely don't have to stringify adminStatus.isAdmin.
context['adminStatus'] = adminStatus.isAdmin
If passed to the context as a boolean, you should be able to use this expression in the template:
{% if adminStatus %}

How to change template based on user authentication in django

If user successfully login i need to show one template. if user not login i need to show another template.
I created two templates one is base.html another one is base_login.html template.
IF user successfully login i need to call base_login.html other wise base.html. i am using below to achieve this. it's not giving expected result. How do achieve this?
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
{% extends "base_login.html" %}
{% else %}
{% extends "base.html" %}
{% endif %}
If your template goes invalid, I suggest you to it at the views.py, an example:
from django.shortcuts import render, render_to_response
def homepage(request):
template_name = 'homepage.html'
extended_template = 'base_login.html'
if request.user.is_authenticated():
extended_template = 'base.html'
return render(
request, template_name,
{'extended_template': extended_template, ...}
)
# homepage.html
{% extends extended_template %}
{% block content %}
{% if request.user.is_authenticated %}
Hello {{ request.user }}
{% endif %}
{% endif %}
Note: if function of render still doesn't work well, please try with render_to_response such as this answer: https://stackoverflow.com/a/1331183/6396981

Django template is not displaying

Assuming my model contains data, I have myapp/views.py:
from django.template import RequestContext
from django.shortcuts import render
from .models import History
import datetime
def live_view(request):
context = RequestContext(request)
plays_list = History.objects.filter(date=datetime.date(2016,04,22))
context_list = {'plays':plays_list}
return render(request,'live.html',context_list)
myapp/templates/live.html:
{% extends 'base.html' %}
{% block content %}
{% for key, value in context_list.items %}
{{ value }}
{% endfor %}
{% endblock %}
myapp/urls.py:
from myapp.views import live_view
urlpatterns = [url(r'^live/$', live_view, name="live"),]
The output is a page that renders only the base.html template, with no content in the body. What's wrong with my view function or template rendering? Should I be inheriting from TemplateView?
You don't pass anything called context_list to the template. What you pass is the contents of that dict, which in this case is just plays.

django feedparser limit the result

im doing something with feedparser: i have a templatetag for display "news" in my home page, but , how ill limit the feedparser result?
inclusion tag
from django.template import Template, Library
import feedparser
register = Library()
#register.inclusion_tag('rss_render.html')
def rss_render(object): #RSS URL "object"
rss = feedparser.parse(object)
return {'rss': rss}
template
<ul>
{% for r in rss.entries %}
<li> {{ r.title }}</li>
{% endfor %}
</ul>
Take this Django snippet for example.
You can use Django's slice template tag:
{% for r in rss.entries|slice:":10" %}
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice

Django template tag + template with user.is_authenticated doesn't work

I have a strange problem, in my settings file everything is enabled that needs to be enabled for user.is_authenticated use in a template.
I have the following template tag code:
from django import template
from progmatic.cms.models import navigation, navigation_item
from django.template.defaultfilters import slugify
from django.shortcuts import render_to_response
from django.template import RequestContext
register = template.Library()
""" Gets the menu items you have entered in the admin.
No arguments are accpeted"""
def get_hoofd_menu( ):
menu = navigation.objects.get( slug = "hoofd-menu");
mcontent = navigation_item.objects.filter( parent_menu = menu);
return { 'mcontent' : mcontent }
def get_sub_menu( menu ):
menu = navigation.objects.get( slug = slugify(menu) )
mcontent = navigation_item.objects.filter( parent_menu = menu )
c = RequestContext( request, { 'mcontent': mcontent,} )
return render_to_reponse('menu.html', RequestContext(request, { 'mcontent' : mcontent }) )
register.inclusion_tag('menu.html')( get_hoofd_menu )
register.inclusion_tag('menu.html')( get_sub_menu )
And the template (menu.html) is as follows:
{% block mainmenu %}
<ul>
{% for content in mcontent %}
{% if content.login_required %}
{% if content.to_page %}
<li>{{ content.name }}</li>
{% endif %}
{% if content.to_url %}
{% if content.external %}
<li>{{ content.name }}</li>
{% else %}
<li>{{ content.name }}</li>
{% endif %}
{% endif %}
{% else %}
{% if content.to_page %}
<li>{{ content.name }}</li>
{% endif %}
{% if content.to_url %}
{% if content.external %}
<li>{{ content.name }}</li>
{% else %}
<li>{{ content.name }}</li>
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% if user.is_authenticated %}
JEEEEEEEJ LOGGED IN
{% else %}
Not logged in
{% endif %}
{% endblock %}
But it always returns Not logged in even when i am logged in...
Does anybody has a clue what is wrong with this code?
Thanks in advance.
Greetings,
Bloeper
Do you have django.core.context_processors.auth in TEMPLATE_CONTEXT_PROCESSORS setting?
Another thing to try is your render_to_reponse syntax. according to the docs, it should be
return render_to_response('my_template.html',
my_data_dictionary,
context_instance=RequestContext(request))
Do you have any other context processors registered? Do they set user?
I recommend running under the dev server and do something like:
rc = RequestContext(request, ... params ...)
user = rc.get('user')
print user.username, user.is_authenticated()
If you don't get the values you expect, then you need to dig deeper. The following should iterate through all context dicts and show you which one(s) contain a value for 'user'. The first one will be what the template sees.
rc = RequestContext(request, ... params ...)
for d in rc:
print d
First of all thanks for all the help.
I found the solution thanks to all of you :)
Turns out i needed to pass the request object in every view and needed to put it as an argument in my template tag.
Solution code:
from django import template
from progmatic.cms.models import navigation, navigation_item
from django.template.defaultfilters import slugify
from django.shortcuts import render_to_response
from django.template import RequestContext
from itertools import chain
register = template.Library()
""" Gets the menu items you have entered in the admin.
No arguments are accepted"""
def get_hoofd_menu( request ):
menu = navigation.objects.get( slug = "hoofd-menu");
mcontent = navigation_item.objects.filter( parent_menu = menu, login_required = False);
if request.user.is_authenticated and not request.user.is_anonymous():
mmcontent = navigation_item.objects.filter( parent_menu = menu, login_required = True )
else:
mmcontent = ""
final_menu = list(chain(mcontent,mmcontent))
return { 'mcontent' : final_menu }
#return render_to_response('menu.html', { 'mcontent' : mcontent } )
def get_sub_menu( request, menu ):
menu = navigation.objects.get( slug = slugify( menu ) )
mcontent = navigation_item.objects.filter( parent_menu = menu, login_required = False )
if request.user.is_authenticated and not request.user.is_anonymous():
mmcontent = navigation_item.objects.filter( parent_menu = menu, login_required = True )
else:
mmcontent = ""
final_menu = list(chain(mcontent,mmcontent))
return { 'mcontent' : final_menu }
#return render_to_response('menu.html', { 'mcontent' : mcontent })
register.inclusion_tag('menu.html')( get_hoofd_menu )
register.inclusion_tag('menu.html')( get_sub_menu )
Thanks for al the help :)
do you have django.contrib.auth and django.contrib.sessions in your settings file?
where is the actual code that checks if the user is authenticated? If you check for it in the template, you should provide some indivcation when passing parameters from the view to the template.
For me it works when I do this at the top:
from django.contrib.auth.decorators import login_required
and decorate all the views where it's important, e.g:
#login_required
def get_hoofd_menu( ):
it's all mentioned in the overview (a little above halfway through)