Electronics & Programming

develissimo

Open Source electronics development and programming

  • You are not logged in.
  • Root
  • » Django
  • » Nested iteration through related models [RSS Feed]

#1 Dec. 21, 2010 21:49:03

D.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

Nested iteration through related models


Let's say I have the following models:

class Group(models.Model):
group_name = models.CharField(max_length=20)

class Person(models.Model):
group = models.ForeignKey(Group)
name = models.CharField(max_length=50)

How do I get an output of the following?

GroupA: John, Stacy, Pete
GroupB: Bob, Bill, Mary

I want to cycle through the groups and then output the people in each group.
In rough pseudo-code:

groups = Group.objects.all()

for g in groups:
print g.group_name, ": "
for p in g.person_set.all:
print p.person

However, this leads to a query being run for each person in order to access
the person's name, which I find to be really unnecessary. I only want to run
one query per group -- will I have to use raw SQL to do this? My initial
thought was to run a query that returns all the people in a group, and then
cycling through the queryset to append the names into a list and then
attaching the list to the project object.

--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to
django-users+unsubscr...@googlegroups.com.
For more options, visit this group athttp://groups.google.com/group/django-users?hl=en.

Offline

#2 Dec. 21, 2010 21:59:52

Javier G.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

Nested iteration through related models


in the view:
persons = Person.objects.all().order_by('group')

in the template:
{% for p in persons %}
{% ifchanged p.group %}
{{p.group}}:
{%endifchanged%}
{{p.name}}
{% endfor %}


--
Javier

--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to
django-users+unsubscr...@googlegroups.com.
For more options, visit this group athttp://groups.google.com/group/django-users?hl=en.

Offline

#3 Dec. 22, 2010 10:41:16

Tom E.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

Nested iteration through related models


On Tue, Dec 21, 2010 at 9:48 PM, Dopster <ken.kyhu...@gmail.com> wrote:
> Let's say I have the following models:
>
> class Group(models.Model):
>     group_name = models.CharField(max_length=20)
>
> class Person(models.Model):
>     group = models.ForeignKey(Group)
>     name = models.CharField(max_length=50)
>
> How do I get an output of the following?
>
> GroupA: John, Stacy, Pete
> GroupB: Bob, Bill, Mary
>
> I want to cycle through the groups and then output the people in each group.
> In rough pseudo-code:
>
> groups = Group.objects.all()
>
> for g in groups:
>   print g.group_name, ": "
>   for p in g.person_set.all:
>      print p.person
>
> However, this leads to a query being run for each person in order to access
> the person's name, which I find to be really unnecessary. I only want to run
> one query per group -- will I have to use raw SQL to do this? My initial
> thought was to run a query that returns all the people in a group, and then
> cycling through the queryset to append the names into a list and then
> attaching the list to the project object.
>

Are you sure? What you have written should result in precisely what
you asked for, 1 query to get the list of groups, 1 query per group to
get the list of users. Your pseudo-code is a little wrong (for p in
g.person_set.all(): print p.person - isn't p already a person? :), but
if I correct that (and use standard contrib.auth models):

>>> from django.contrib.auth.models import User, Group
>>> from django.db import connection
>>> for g in Group.objects.all():
... print g.name, ':'
... for u in g.user_set.all():
... print u.get_full_name()
...
...
>>> pprint(connection.queries)



On Tue, Dec 21, 2010 at 9:59 PM, Javier Guerra Giraldez
<jav...@guerrag.com> wrote:
> in the view:
> persons = Person.objects.all().order_by('group')
>
> in the template:
> {% for p in persons %}
>  {% ifchanged p.group %}
>      {{p.group}}:
>  {%endifchanged%}
>  {{p.name}}
> {% endfor %}
>
>

No, that's even worse - that is one query to get the list of people,
and one query per person to build their group model object. If the
ifchanged checked 'p.group_id' instead of 'p.group', then that avoid
unnecessarily instantiating the group object, and would cut it down to
num_groups + 1 queries.

Cheers

Tom

--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to
django-users+unsubscr...@googlegroups.com.
For more options, visit this group athttp://groups.google.com/group/django-users?hl=en.

Offline

  • Root
  • » Django
  • » Nested iteration through related models [RSS Feed]

Board footer

Moderator control

Enjoy the 14th of December
PoweredBy

The Forums are managed by develissimo stuff members, if you find any issues or misplaced content please help us to fix it. Thank you! Tell us via Contact Options
Leave a Message
Welcome to Develissimo Live Support