【问题标题】:Django quickly get latest in one to many relationDjango 在一对多关系中快速获取最新信息
【发布时间】:2016-12-17 22:24:28
【问题描述】:

我在 Django 中有一个这样的模型

class Artist(models.model):
    pass

class Track(models.model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)

我只有几百个Artists,我想在页面上显示他们最新的Track。我可以快速获取所有Artists,但是当有数千首曲目时,获取他们最新的Track 被证明是昂贵的。

latest_track = artist.track_set.latest('when') # really expensive

我向艺术家添加曲目的方式允许我轻松设置艺术家的最新曲目(即我不必担心多个线程)。这让我觉得我应该只存储一个字段Artist#latest_track,但我不知道如何对其建模,因为它不是真正的OneToOneField,这是我能找到的最接近的东西。

我也考虑过使用cached_property,但我没有在正确的时间使缓存失效的好方法。此外,cached_property 似乎只在运行时设置,所以如果我重新启动我的应用服务器,它将需要重做所有查询。

我在这里做什么?

【问题讨论】:

    标签: python django one-to-many


    【解决方案1】:

    我打赌你只需要prefetch_related 艺术家:

    for artist in Artist.objects.all().prefetch_related('track_set'):
        latest_track = artist.track_set.latest('when') #should be no db hit
    

    如果它仍然很慢,您需要检查生成的 sql(django 调试工具栏、数据库日志)并查看发生了什么,通常缓慢不是来自您期望的地方。

    【讨论】:

    • 这不是正确答案!!艺术家.track_set.latest('when') 命中数据库!为了不破坏 prefetch_related 您必须使用纯 Python 进行迭代,而不执行另一个查询。
    猜你喜欢
    • 2021-07-23
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多