开发者

A left outer reverse select_related in Django?

开发者 https://www.devze.com 2023-01-02 02:15 出处:网络
Imagine the following model: class Parent(Model): ... class Child(Model) father = ForeignKey(Parent) ... Some parents have children, others do not (they\'re not parents in the real meaning, it\'s

Imagine the following model:

class Parent(Model):
    ...

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

Some parents have children, others do not (they're not parents in the real meaning, it's just a fictional name).

I would like to make the following query开发者_StackOverflow: I want to list all the Parents, and if they have children, bring me the children too. That would be the equivalent of a left outer join to Child table, that is:

select * from app_parent left join app_child on child_father_id=parent_id

This way, when I invoke Parent.child_set in my template, I won't hit the database a gazillion times. Is there a way to do that? Thanks


Starting from Django 1.4 prefetch_related does what you want.

Parent.objects.prefetch_related('child_set')

Related(!) django docs : https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related.


In this case, I think the best thing to do is list the children, then get the parent from them, like this:

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

Then in the template, possibly use a regroup (note the order_by above):

{% 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>


in django 1.3

Child.objects.select_related('father')
#sql: select * from app_child left join app_parent  on child_father_id=parent_id


I think you are looking for select_related()

0

精彩评论

暂无评论...
验证码 换一张
取 消