【问题标题】:A left outer reverse select_related in Django?Django中的左外反向select_related?
【发布时间】:2011-02-27 20:49:14
【问题描述】:

想象以下模型:

class Parent(Model):
    ...

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

有些父母有孩子,有些则没有(他们不是真正意义上的父母,只是一个虚构的名字)。

我想进行以下查询:我想列出所有的父母,如果他们有孩子,把孩子也带给我。这相当于对子表的左外连接,即:

select * from app_parent left join app_child on child_father_id=parent_id

这样,当我在模板中调用 Parent.child_set 时,我不会多次访问数据库。有没有办法做到这一点? 谢谢

【问题讨论】:

  • 我决定不应该使用这种方法;真的没有任何支持。似乎最好的方法是从最子级的表中进行选择,然后,如果需要,根据情况在父字段中使用“重新组合”模板标签或 set() 函数。
  • 重组方法的一个缺点是它不会得到不存在的父母

标签: django left-join django-queryset django-select-related


【解决方案1】:

从 Django 1.4 开始 prefetch_related 做你想做的事。

Parent.objects.prefetch_related('child_set')

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

【讨论】:

  • 我认为这与 OP 所要求的不同。我刚刚运行了 select_prefetch,它实际上运行了 2 个查询: 1. select * from parents; 2. select * from child where parent_id IN (-bunch-of-comma-separated-ids-from-query-1-go-here-) 这是它应该如何工作还是我做错了什么?
【解决方案2】:

在这种情况下,我认为最好的办法是列出孩子,然后从他们那里得到父母,像这样:

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>

【讨论】:

    【解决方案3】:

    在 django 1.3 中

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

    【讨论】:

      【解决方案4】:

      我想你在找select_related()

      【讨论】:

      • 不完全;就我而言, select_related() 没有反向查找,它只向前看。
      • 你确定吗?我查看了 Django 文档,它说它适用于 1:1 关系,但不确定 ForeignKey-relations...
      • 根据文档 select_related() 可以从 Django 1.2 开始进行反向查找,但仅适用于 OneToOneFields。
      猜你喜欢
      • 2016-10-05
      • 2014-06-01
      • 2011-12-27
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2019-12-01
      相关资源
      最近更新 更多