Boolean check inside a for loop in a Django template - django

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 %}

Related

django template falling into unexpected logic

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.

No reverse match error but the function exists?

I am trying to implement a renew function for a key inventory system. But when I render that page, it shows a Reversematcherror even though I mapped the correct URL and used the correct function name.
Here is my template:(The URL tag is on the super long line all the way to the right)
{% block content %}
<h1>All Borrowed Keys</h1>
{% if keyinstance_list %}
<ul>
{% for keyinst in keyinstance_list %}
<li class="{% if keyinst.is_overdue %}text-danger{% endif %}">
{{keyinst.roomkey}}
({{ keyinst.due_back }})
{% if user.is_staff %}
- {{ keyinst.borrower }}
{% endif %}
{% if perms.catalog.can_mark_returned %}
- Renew
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no keys borrowed.</p>
{% endif %}
{% endblock %}
My urls.py:
path('key/<uuid:pk>/renew/', views.renew_key_user, name='renew-key-user'),
path('key/<int:pk>/detail', views.KeyDetailView.as_view(), name='roomkey-detail'),
Views.py:
#permission_required('catalog.can_mark_returned')
def renew_key_user(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk = pk)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = RenewKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.due_back = form.cleaned_data['renewal_date']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-borrowed-keys') )
# If this is a GET (or any other method) create the default form.
else:
proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
form = RenewKeyForm(initial={'renewal_date': proposed_renewal_date,})
return render(request, 'catalog/roomkey_renew_user.html', {'form': form, 'keyinst':key_inst})
class KeyDetailView(generic.DetailView):
model = RoomKey
The error is saying
Reverse for 'views.renew_key_user' not found. 'views.renew_key_user'
is not a valid view function or pattern name.
Update this line in your template.
Renew
as name in url is renew-key-user
path('key/<uuid:pk>/renew/', views.renew_key_user, name='renew-key-user'),
Your URL name contains - hyphen not _ underscore
change this renew_key_user to renew-key-user in your template
Renew
Your template is asking for 'roomkey-detail' but the urls snippet you've provided only shows a url named 'renew-key-user'. Unless there are more url definitions you're not showing us, the code is failing as expected since it can't find a URL with the name you're asking for.

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()

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

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 %}