使用django ORM优化获取只有最新孩子的父母的方式

Sof*_*tic 6 python mysql sqlite django django-models

我们想以这样的方式取得父母的孩子,它给了我最近的10个父母,每个父母只有一个最新的儿童记录.

例如:

Category
- id
- name
- created_date

Item
- id
- name
- category
- created_date
Run Code Online (Sandbox Code Playgroud)

使用上面指定的模型结构,我想获取最新的10个类别以及每个类别的最新子项.

只有一个查询到服务器我想访问所有数据.

Category1.name, Category1.id, LatestItemForCat1.name, LatestItem1ForCat1.created_date
Category2.name, Category2.id, LatestItemForCat2.name, LatestItem1ForCat2.created_date
Category3.name, Category3.id, LatestItemForCat3.name, LatestItem1ForCat3.created_date
Run Code Online (Sandbox Code Playgroud)

使用django ORM实现此优化的最佳方法是什么?

这可以通过以下sql查询获得.我更愿意使用django ORM来解决这个问题.或者更好的SQL查询.

select c.name, c.id, i.name, i.created_date
from
    category c
inner join
    item i
on c.id = i.category_id
where i.id = (select id from item order by created_date desc limit 0,1)
limit 10
Run Code Online (Sandbox Code Playgroud)

Pau*_*ine 3

您可以诉诸原始 SQL,并且您的查询看起来不错(只是最后在限制之前缺少“order by c.created_date desc”。

原始 SQL 解决方案中的子查询并不比返回类别模型中最后 10 个条目的方法好多少,如下(未经测试的)示例:

class Category(models.Model):
    ...
    def last10items(self):
        return self.item_set.order_by('-created_date')[:10]
Run Code Online (Sandbox Code Playgroud)

我们谈论的是最大100条记录,我不会担心效率,因为后续查询就像命中缓存(有几层缓存:django、数据库和操作系统)。这样您就可以传递最后 10 个类别并从模板中调用 last10items:

{% for category in categories %}
  ...
  {% for item in category.last10items %}
      ...
Run Code Online (Sandbox Code Playgroud)

我确信有些混蛋会因为我这样说而对我投反对票:除非需要,否则不要尝试优化某些东西。在许多情况下,我很惊讶在对代码进行分析之前,我对一种方法相对于另一种方法的效率的认识是多么错误。阅读“ Python 模式 - 优化轶事”。