How can I filter query sets in a django template?

1,072 views
Skip to first unread message

codecowboy

unread,
Apr 5, 2009, 3:49:57 PM4/5/09
to Django users
I posted a question earlier today about circular imports (http://
groups.google.com/group/django-users/t/6119e979131c8c25). I now have
a follow question to that. I've got the following view logic.

def portal(request):
scientist_id = 1
s = get_object_or_404(Scientist, pk=scientist_id)
return render_to_response('scientists/portal.html',
{'scientist':s})

Now, Scientists are related (many-to-many) to Conferences through
ConferenceAttendee. Both of these models are created in a different
app. I won't paste them in unless someone needs to see them in order
to answer my question.

I only want to loop through conferences that this scientist is
presenting. (ConferenceAttendee.presenter=True). I have tried
following the docs (http://docs.djangoproject.com/en/dev/topics/db/
queries/#field-lookups-intro), but it seems that you can only call the
filter method in python files like views.py or models.py. I've tried
replacing the loop code below with "for ...conference._set.filter(...)
but python gives me errors when I do that. Here is my template logic.

<h2>Your Presentations</h2>

<ul>
{% for conference in scientist.conference_set.all %}
<li><a href="/conferences/{{ conference.id }}">
{{ conference.title }}</a><a href=""><img src="/site_media/images/
portal_start_button.jpeg" /></a></li>
{% endfor %}

</ul>

I've been stuck on this one for days now so any help would be greatly
appreciated. Please do point me to any articles that I may have
missed that already answer this post.

Thank you,

Guy

Florian Strzelecki

unread,
Apr 5, 2009, 4:13:13 PM4/5/09
to django...@googlegroups.com
Did you try to look at Inclusion Tag ?
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags

In template you are not allowed to use some python code... but with an inclusion tag, you will be able to write this :

{% load related_conferences %}
{% related_conferences scientist %}

And your inclusion tag may be this :
@register.inclusion_tag('path/to/tag/related_conferences.html')
def related_conferences(scientist):
# define here list_of_conferences
return {'list': list_of_conferences}
The inclusion tag have been created for this : move python code into python file ! Not into template files.

I hope this will help you.
And sorry for my English, I'm french. :)


2009/4/5 codecowboy <guy....@gmail.com>

Daniel Roseman

unread,
Apr 5, 2009, 4:18:29 PM4/5/09
to Django users
The issue is that in a template, you can't call any method or function
that requires an argument. There are two ways of dealing with this:
create a custom template tag or filter, or create a method that
doesn't need arguments.

In this case, I'd go with the second option. Just create a method on
the Scientist model that returns a queryset of conferences at which
they are a presenter.

class Scientist(models.Model):
.... blah ....

def presenting_conferences(self):
return self.conferences_set.filter(presenter=True)
#or whatever the filter is

and in the template:

{% for conference in scientists.presenting_conferences %}
etc.
--
DR.

codecowboy

unread,
Apr 8, 2009, 9:45:08 PM4/8/09
to Django users
Thank you Daniel and Florian (Merci beaucoup. Je parle francais un
petit).

I think that I will be able to use both templates and custom model
methods to accomplish what I am trying.



On Apr 5, 4:18 pm, Daniel Roseman <roseman.dan...@googlemail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages