harryghgim
harryghgim

Reputation: 1570

get one object in queryset iteration

I have two models, A and B, and B is ForienKey relationship to A.

I want to check each object in queryset and if it has certain fields then I want to display it in template.

Below is my template example:

{% for a in a_qs %}
<tr>
  <th>{{ a.b_set.first.a_field }}</th>
  <th>{{ a.b_set.first.another_field }}</th>
{% endfor %}

They work fine, but I want to apply something like get method in queryset. Below is what I want to achieve:

{% for a in a_qs %}
<tr>
  <th>{{ a.b_set.get(a_field_in_B='hello').a_field }}</th>
  <th>{{ a.b_set.get(a_field_in_B='hello').another_field }}</th>
{% endfor %}

I understand that something above is not possible and I want to give some change to my views or models, but I don't know where to start.

Below is something like my views.py snippet:

a_qs = A.objects.all()
a_obj = a.b_set.get(a_field='something') # a is not defined yet. I want every a in a_qs to be checked

Thanks for your advice in advance.

Upvotes: 1

Views: 73

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

Django templates are deliberately restricted to not allow method calls with parameters, as well as subscripts, etc. The reason is that business logic does not belong in the templates, but in the views.

You can make use of a Prefetch object [Django-doc] to load objects per item. This will normally be faster as well, since all the related objects are loaded in bulk:

from django.db.models import Prefetch

a_qs = A.objects.prefetch_related(Prefetch(
    'b_set',
    B.objects.filter(a_field='something'),
    'b_filtered'
))

If you pass this to the template, you can render this with:

{% for a in a_qs %}
<tr>
  <th>{{ a.b_filtered.0.a_field }}</th>
  <th>{{ a.b_filtered.0.another_field }}</th>
</tr>
{% endfor %}

or more elegant:

{% for a in a_qs %}
<tr>
  {% with b_first=a.b_filtered.0 %}
  <th>{{ b_first.a_field }}</th>
  <th>{{ b_first.another_field }}</th>
  {% endwith %}
</tr>
{% endfor %}

Upvotes: 1

Related Questions