Django:在一个查询中加入两个表

Django: Join two tables in a single query

在我的模板中,我有一个 table,我想用来自两个使用外键的不同 table 的数据填充它。

我在谷歌搜索时找到的解决方案是使用 values(),下面是我的查询集示例:

data = Table1.objects.all().filter(date=today).values('table2__price')

我的模板

    {% for item in data %}
        <tr class="original">
          <td>{{ item.fruit }}</td>
          <td>{{ item.table2__price }}</td>
        </tr>
    {% endfor %}

它确实从 table2 获取价格,但它也使表 1 中的数据 (item.fruit) 消失。如果我删除值字段,表 1 会相应地填充。

有人对我做错了什么有任何反馈吗?

谢谢

如果你利用.values(…) [Django-doc], then you retrieve a queryset of dictionaries, that only contains the values specified. This is not a good idea. Not only because as you found out, it wiill thus no longer use the values in the model, but you will "erode" the model layer as well: it is no longer a Table1 object, but a dictionary. Which is a form of a primitive obsession antipattern [refactoring.guru].

您可以使用 .annotate(…) [Django-doc] 为由此查询集产生的元素添加额外的属性:

from django.db.models import F

data = Table1.objects.filter(date=today).annotate(
    <b>table2__price=F('table2__price')</b>
)

如果从 Table1Table2ForeignKey(或 OneToOneField),您可以 select [=16= 的列] 在与 .select_related(…) [Django-doc]:

相同的查询中
data = Table1.objects.filter(date=today)<b>.select_related('table2')</b>

在模板中,您可以使用:

{{ item.fruit }}
{{ item<b>.table2.price</b> }}
{{ item<b>.table2.other_attr</b> }}

.select_related(…) 部分不是绝对必要的,但如果没有它,它将对每个 项目进行额外的查询 ,因此这将产生一个 N+1 题.