title: Django: getting the list of related records for a list of objects
body: <p>I have two models related one-to many:</p>
  
  <pre><code>class Person(models.Model):
      name      = models.CharField(max_length=255);
      surname   = models.CharField(max_length=255);     
      age       = models.IntegerField(); 
  
  
  class Dog(models.Model):
      name      = models.CharField(max_length=255);
      owner     = models.ForeignKey('Person');
  </code></pre>
  
  <p>I want to output a list of persons and, below each person a list of dogs he has. Here's how I can do it:</p>
  
  <p>in view:</p>
  
  <pre><code>persons = Person.objects.all()[0:100];
  </code></pre>
  
  <p>in template:</p>
  
  <pre><code>{% for p in persons %}
      {{ p.name }} has dogs:&lt;br /&gt;
      {% for d in persons.dog_set.all %}
          - {{ d.name }}&lt;br /&gt;
      {% endfor %}
  {% endfor %}
  </code></pre>
  
  <p>But if I do it like that, Django will execute 101 SQL queries which is very inefficient.</p>
  
  <p>I tried to make a custom manager, which will get all the persons, then all the dogs and links them in python, but then I can't use paginator (my another question: <a href="https://stackoverflow.com/questions/2532475/django-paginator-raw-sql-query">Django: Paginator + raw SQL query</a> ) and it looks quite ugly.</p>
  
  <p>Is there a more graceful way doing this?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Solution based on blog entry by @Daniel Roseman</p>
  
  <pre><code>all_objects = Person.objects.select_related().all();
  
  paginator = Paginator(all_objects, 100);
  
  try:
      page = int(request.GET.get('page', '1'))
  except ValueError:
      page = 1
  
  try:
      current_page = paginator.page(page)
  except (EmptyPage, InvalidPage):
      current_page = paginator.page(paginator.num_pages)
  
  person_list = dict([(obj.id, obj) for obj in current_page.object_list])
  id_list = [obj.id for obj in current_page.object_list]
  
  objects = Dog.objects.filter(owner__id__in=id_list)
  
  relation_dict = {}
  for obj in objects:
      relation_dict.setdefault(obj.owner_id, []).append(obj)
  
  for id, related_items in relation_dict.items():
      person_list[id].dogs = related_items
  </code></pre>