Django Template - Need to use filter() - django

I am kinda stuck.
Here is the situation. I have 2 for loops. One that loops through categories and the other one that loops through a match set. Here is the problem:
I need to get all the matches from that category...
Here is what I have:
{% for category in tournament.get_categories %}
<div class="line" style="margin-top: 25px; margin-bottom: 40px;"></div>
<div class="container">
<h3 class="margin-reset" id="{{ category.slug }}">{% trans "Matches schedule" %}<span> | {{ category.name }}</span></h3>
<table class="standard-table table">
<thead>
<tr>
<th>Match</th>
<th>Heure</th>
<th>Plateau</th>
<th>Équipe bleu</th>
<th>Équipe gris</th>
<th>Équipe noir</th>
<th>Résultat</th>
</tr>
</thead>
<tbody>
{% for match in tournament.match_set.filter(category=category) %}
<tr>
<td>{{ match.match_num }}</td>
<td>{{ match.time }}</td>
<td>{{ match.plateau }}</td>
<td>{{ match.blue_team.name }}</td>
<td>{{ match.grey_team.name }}</td>
<td>{{ match.black_team.name }}</td>
<td>{{ match.get_url_string }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
As you guys probably guessed it, I get this error:
Could not parse the remainder: '(category=category)' from 'tournament.match_set.filter(category=category)'
What can I do?
Thanks,
Ara
EDIT:
Here is the solution:
The custom tag:
#register.filter
def get_matches_by_category(value, category):
return value.match_set.filter(category=category)
And the use:
{{ tournament|get_matches_by_category:category }}

I created a custom templatetag and used that filter.
It's kinda an overkill but...oh well.

What I have done in a very similar case is pass the list of categories to the template, adding them a new attribute with the matches, like:
for category in categories:
category.matches = Match.objects.filter(tournament=tournament, category=category)
It's kinda slow, but you can work it and reduce the number of queries
I would pass the categories list to the template after this

Related

How to ADD for loop result in templates

views.html
{% for products in product %}
<tr>
<td>{{ products.quantity_deliver1 }}</td>
<td>{{ products.quantity_deliver2 }}</td>
<td>{{ Code Here }}</td>
</tr>
{% empty %}
<tr>
<td colspan="3" class="text-center bg-warning">No Products</td>
</tr>
{% endfor %}
How do I add products.quantity_deliver1 + products.quantity_deliver2 and output the sum in the 3rd data cell.
You can use builtin django template tag add for adding two.
{{products.quantity_deliver1|add:products.quantity_deliver2}}
Ref - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#add

How to print only certain cells of my table in Django templates?

I am developing an app in Django.
I have on my template (code 0):
{% for row in query_result %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
Let's suppose I want my template to print only the first and the third column of my matrix, how can I indicate to my template a specific cell?
I tryed with
{% for row in query_result %}
<tr>
<td >{{ cell[0] }}</td>
<td >{{ cell[2] }}</td>
</tr>
{% endfor %}
but it does not work.
EDIT:
As suggested, I tryed with (code 2):
{% for row in query_result %}
<tr>
<td >{{ cell.0 }}</td>
<td >{{ cell.2 }}</td>
</tr>
{% endfor %}
But this somehow erases the content of my cells, see here below.
results of Code 0:
results of code 2:
You can obtain an item at an index in Django's template engine by fetching it as you would fetch an attribute, so:
{% for row in query_result %}
<tr>
<td >{{ row.0 }}</td>
<td >{{ row.2 }}</td>
</tr>
{% endfor %}
That being said, I strongly advise to try to fix the problem upstream: instead of rendering a subset, take a look what you can do to limit the "columns" in query_result.
or you can unpack the elements and put the second item in a "throwaway" variable:
{% for cell0, __, cell2 in query_result %}
<tr>
<td >{{ cell0 }}</td>
<td >{{ cell2 }}</td>
</tr>
{% endfor %}
Use looks like {{ cell.0 }} this. The Django docs explain in the section variables and lookups.
So you would do something like:
{% for row in query_result %}
<tr>
<td >{{ cell.0 }}</td>
<td >{{ cell.2 }}</td>
</tr>
{% endfor %}

Django Template : Combine 2 loops over different lists

I'm wondering how I can combine these 2 querysets in my template in order to loop over them.
requests = Download.objects.values('pub__age_id').annotate(count=Count('pub__age_id'))
max_download_number = Download.objects.values('pub__age_id').annotate(max_usage=Max('usage'))
context = {'requests': requests, 'max_download_number': max_download_number}
In my template :
{% for item in requests %}
{% for element in max_download_number %}
<tr>
<td>{{ item.pub__age_id }}</td>
<td><span class="badge alert-info">{{ item.count }}</span></td>
<td>{{ element.max_usage }}</td>
<td>Something</td>
</tr>
{% endfor %}
{% endfor %}
It displays wrong loops :
Why don't you combine it in the view:
requests = Download.objects.values('pub__age_id').annotate(count=Count('pub__age_id')).annotate(max_usage=Max('usage'))
and then in the template:
<td>{{ item.pub__age_id }}</td>
<td><span class="badge alert-info">{{ item.count }}</span></td>
<td>{{ item.max_usage }}</td>

Django-- Get model fields in template only for current user

First of all, I know there are lot of questions about accessing model in template but let me explain why this is different.
I want profile page where User can see their details. I am able to do that but with one little bug. If there are 3 Users(say A, B,C) and User A want to see his profile he sees it three time. Like this:
How do I stop the loop after one iteration so that the User only get's his profile information once.
This is my URL:
url(r'^profile/$', views.IndexView.as_view(), name='profile'),
Views.py:
class IndexView(generic.ListView):
template_name = 'profile.html'
def get_queryset(self):
return Profile.objects.all()
and profile.html:
{% if user.is_authenticated %}
{% for profile in object_list %}
<h1>{{ request.user }}'s Profile</h1>
<table>
<tr>
<td>Username:</td>
<td>{{ user.username }}</td>
</tr>
<tr>
<td>First Name:</td>
<td>{{ user.first_name }}</td>
</tr>
<tr>
<td>Last Name:</td>
<td>{{ user.last_name }}</td>
</tr>
<tr>
<td>Email:</td>
<td>{{ user.email }}</td>
</tr>
<tr>
<td>Personal Info:</td>
<td>{{ user.profile.personal_info }}</td>
</tr>
<tr>
<td>Job Title:</td>
<td>{{ user.profile.job_title }}</td>
</tr>
<tr>
<td>Department:</td>
<td>{{ user.profile.department }}</td>
</tr>
<tr>
<td>Location:</td>
<td>{{ user.profile.location }}</td>
</tr>
<tr>
<td>Expertise:</td>
<td>{{ user.profile.expertise }}</td>
</tr>
<tr>
<td>Phone Number:</td>
<td>{{ user.profile.phone_number }}</td>
</tr>
<tr>
<td>Contact Skype:</td>
<td>{{ user.contact_skype }}</td>
</tr>
<tr>
<td>Contact Facebook:</td>
<td>{{ user.contact_facebook }}</td>
</tr>
<tr>
<td>Contact Linkedin:</td>
<td>{{ user.profile.contact_linkedin }}</td>
</tr>
</table>
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<a href={% url 'profile_edit' %}><input type="button" class = " col-sm-offset-2 btn bk-bs-btn-warning " name="cancel" value="Edit" /></a>
</div>
</div>
</form>
{% endfor %}
{% else %}
<h2>Please login to see your Profile</h2>
{% endif %}
I am a newbie to django, thanks is advance.
You're looping over all Profile's but not actually using this data in the loop, instead you're using user.profile.
This means that you likely have 3 Profile objects in the database, then for each you display the details of the current user, which isn't desirable.
So you can remove the loop entirely, and just keep its contents that refer to all the user.profile attributes to achieve the desired result.
edit
Looks like user is passed into your template by default, and points to the currently logged in user. So user.profile will return the profile, and this works without doing anything else. So user.profile.personal_info is valid and should work. When you tried to use profile directly, that is not the same thing, and wasn't defined, so profile.personal_info didn't work. Then in your loop you used profile to loop over Profile objects, but this wasn't necessary or was used. Hope this makes sense.

PyCharm says Expected }} after |default in a template

<div class="person_roles_div">
<table>
<thead></thead>
<tbody>
{% for position in person.positions %}
<tr>
<td>{{ position.provider|default:"" }} {{ position.role }}</td>
<td>{{ position.facility|default:"" }}</td>
<td>{{ position.startdate|default:"" }}</td>
<td>{{ position.enddate|default:"" }}</td>
<td>
<button id="remove_position_sk_{{ position.position_sk }}" class="position_remove_button">Remove</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
In the first four td tags that output a context variable and specify a default, PyCharm is highlighting the : and blank space right before and after each ""
The hovertip message is (( or {% expected. The page runs fine.
Any idea what setting I should looking at?
it's "Python template languages". See the screenshot:
Make sure it's set to "Django"