Левый внешний реверс select_related в Django? - PullRequest
28 голосов
/ 04 июня 2010

Представьте себе следующую модель:

class Parent(Model):
    ...

class Child(Model)
    father = ForeignKey(Parent)
    ...

У некоторых родителей есть дети, у других нет (в действительности они не родители, это просто вымышленное имя).

Iхотел бы сделать следующий запрос: Я хочу перечислить всех родителей , и если у них есть дети, принесите мне детей тоже .Это будет эквивалентно левому внешнему соединению с дочерней таблицей, то есть:

select * from app_parent left join app_child on child_father_id=parent_id

Таким образом, когда я вызываю Parent.child_set в моем шаблоне, я не нажмубаза данных в миллион раз.Есть способ сделать это?Спасибо

Ответы [ 5 ]

21 голосов
/ 30 июня 2012

Начиная с Django 1.4 prefetch_related делает то, что вы хотите.

Parent.objects.prefetch_related('child_set')

Связанные (!) Django документы: https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related.

13 голосов
/ 05 июня 2010

Извините, что снова опубликовал ссылку на мой блог, но я написал о методике имитации select_related по обратным отношениям .

6 голосов
/ 21 сентября 2010

В этом случае, я думаю, что лучше всего перечислить детей, а затем получить от них родителей, например:

children = Child.objects.filter(...).select_related('parent').order_by('parent')

Затем в шаблоне, возможно, используйте regroup (обратите внимание на order_by выше):

{% regroup children by parent as parents %}
<ul>
{% for parent in parents %}
    <li>{{ parent.grouper }}
    <ul>
    {% for child in parents.list %}
    ...
    {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>
0 голосов
/ 04 сентября 2011

в Джанго 1,3

Child.objects.select_related('father')
#sql: select * from app_child left join app_parent  on child_father_id=parent_id
0 голосов
/ 04 июня 2010

Я думаю, что вы ищете select_related ()

...