django template falling into unexpected logic - django

I have a view that is supposed to be gathering all the objects for a currently authenticated user from three tables TSFH, TSUH, and TSJH and gather all those objects for the currently logged in user, if that user exists.
However, my view logic is currently falling into the else statement it appears.
Can someone help me debug why this might be happening?
My tables have data for the currently logged in user, so I am not sure why this is happening.
Views.py
def SHO(request):
TSUH = TSUH.objects.filter(FKToUser_id=request.user).all()
TSFH = TSFH.objects.filter(FKToUser_id=request.user).all()
TSJH = TSJH.objects.filter(FKToUser_id=request.user).all()
return render(request, 'page.html', {
'TSUH':HasTSUH,
'TSFH':HasTSFH,
'TSJH':HasTSJH
})
templates/page.html
{% autoescape on %}
{% if HasTSUH %}
{% for t in HasTSUH %}
<li>{{ t.begin }}<span></li>
{% endfor %}
{% elif HasTSFH %}
{{ HasTSFH }}
{% elif TSJH %}
{{ TSJH }}
{% else %}
It appears you haven't done anything yet.
{% endif %}
However it keeps displaying:
It appears you haven't done anything yet.
what am i doing wrong here? thanks

The names in the template are the keys of the context dict. You've used TSUH, TSFH, and TSJH, without the Has.

Related

django template - how to get a dictionary property without using a for loop

Doing this works
{% for comment in comments %}
{{ comment.user }}
{% endfor %}
However, I want to get all the comment.user values in the dictionary without using a for loop. Is this possible?
I ask because I need to do this check
{% if name in comment.user %} # check if name is in any one of the comments
# do something
{% endif %}
Basically, you need to get all the distinct users from comments. You have to do it in the view and pass users queryset back into the template:
users = User.objects.filter(comment__in=comments).distinct()

Boolean check inside a for loop in a Django template

In a Django template I have the following for loop
{% for document in documents %}
<li>{{ document.docfile.name }}</li>
{% endfor %}
Through this loop I am showing the user all the uploaded files of my app.
Now say that I want to show the user only the files he/she has uploaded.
I have the current user in the variable {{ request.user }}
and also I have the user who did the i-th upload in {{ document.who_upload }}
My question is how can I compare these two variables inside the loop to show only the uploads that have a who_upload field that of the current user?
For example I tried the syntax
{% if {{ request.user }} == {{ document.who_upload }} %}
{% endif %}
but it does not seem to work.
What is the proper syntax for this check?
Thank you !
This should get the job done:
{% if request.user.username == document.who_upload.username %}
{% endif %}
But you should consider performing this logic in your view. This is assuming you're not looping over the entire queryset anywhere else.
views.py
========
from django.shortcuts import render
from .models import Document
def documents(request):
queryset = Document.objects.filter(who_upload=request.user)
return render(request, 'document_list.html', {
'documents': queryset
})
A better option would be to compare the users' primary keys, instead of comparing user objects, which most definitely will be different.
{% if request.user.pk == document.who_upload.pk %}
<span>You uploaded this file</span>
{% endif %}

Compare two table in template

I have two django model, User and Follow.
In the Follow table, I have two attribute a and b which means a following b.
User table is just the django.contrib.auth.User
Let say I am in user A homepage, and A is following B, C and not following D.
I want to list all the username in A's homepage and highlighting those A is following.
In this case B, C should be highlighted and D should not be highlighted.
I was thinking about (pseudocode)
for user in users :
for follow in Following:
if user.username == follow.username:
flag=true
break
if flag:
#print color <p>user.username</p>
else
#print normal..
But I dun think django template allow me to do this.
Is there any other ways to do this?
Here is my code in django template
{% for user in all_user %}
{% for follower in followers %}
{% ifequal user.username follower.follow.username %}
<p class="following">{{user.username}}</p>
{% endifequal %}
{% endfor %}
<p>{{ user.username }}</p>
{% endfor %}
This will duplicate the user that 'A' is following.
Thank you so much
Hm, I would approach this by doing what you have done here, and by passing the variable "flag" to your template, as well as the rest of the objects.
{% if flag == True %}
<do whatever>
{% endif %}
You can also add an attribute to the user in your for loop, then retrieve that in the template.
for user in users :
for follow in Following:
if user.username == follow.username:
user.followed = True
break
Then in your template
{% for user in users %}
{% if user.followed %}
....
{% else %}
....
{% endif %}
{% endfor %}

reduce django db calls

I noticed that my django code calls my database very often with the exact same queries.
I understand that a db hit is made when I actually need the data to display on a page or to evaluate. However, my template code looks like this:
template:
{% if item.listing %}
{{ item.name }} text <strong>{{ item.listing|lowestprice }}</strong> more text
{% else %}
{{ item.name }} even more text
{% endif %}
....
{% for listed_item in item.listing %}
....
{% endfor %}
custom filter:
def lowestprice(value):
try:
val = unicode(value[0].price) + unicode(value[0].symbol)
return val
except:
return "not available"
This code hits my db three times. First on template {% if .. %} second on my custom filter, third on the {% for %} loop.
listing is a method of my models class which is returning a raw SQL queryset with some very expensive joins.
def listing(self):
return Universe.objects.raw("ONE HELL OF A QUERY")
How can I reduce my code to hit the db only once?
Edit: Using with works, but is it possible to avoid db hits on custom filters?
You should use with to do the expensive query once and store it the context.
{% with item.listing as item_listing %}
{% if item_listing %} ... {% endif %} ... etc ...
{% endwith %}

How to know if a checkbox is checked having just the {{ form.checkbox }} form-tag

How can I know if a checkbox is checked (True, 1) having just the {{ form.checkbox }} form-tag?
'activo' is defined as (True, 1) in the db.
My template is:
{{ form.activo }}
RESULTS:
<input id="id_activo" type="checkbox" name="activo" checked="checked"/>
{{ form.activo.data }}
RESULTS:
False
{{ form.activo.value }}
RESULTS:
""
Yet no 1's or True's are coming through. :S
Any hint is appreciated. =')
It is checked if request.POST.has_key('activo') or the {{ form.activo.data }} actually returns True when initialized with request.POST.
Your question isn't quite clear, but maybe your problem has something to do with the fact, that browsers don't put anything in the POST data for an unchecked checkbox.
This made things complicated for me when I had to differentiate between a checkbox not being displayed at all and a displayed checkbox not having been checked. Just from looking at the POST data you can't tell those two cases apart.
Following on from your reply to mbarkhau's answer, using instance= doesn't make the form bound, it just provides default values to the form.
Here's the logic in a template:
{% if form.is_bound %}
{% if form.initial.activo %}
Checked.
{% else %}
Not checked.
{% endif %}
{% else %}
{% if form.activo.data %}
Checked.
{% else %}
Not checked
{% endif %}
{% endif %}
But it makes more sense to do this logic in the view and pass extra context. Something like:
context_data = {...}
if form.is_bound:
activo = form.data.get('activo')
else:
activo = form.initial.get('activo')
context_data['activo'] = bool(activo)
return render_to_response('your_template.html', context_data)
If you want a boolean condition in templates this should work:
{% if form.activo %}
--
{% else %}
---
{% endif %}