【问题标题】:Adding mini caches to django models将迷你缓存添加到 django 模型
【发布时间】:2010-12-15 08:03:28
【问题描述】:

由于 m2m 关系,我遇到了 Django 的性能问题。我有一个包含Something_instance.item_set 的Something 对象列表,因此我多次调用Something_instance.item_set.all()。我想将该查询缓存到 Something_instance 中,这样我就不必运行这么多查询。这可能吗? (这本质上是一种让 select_related() 为 m2m 工作的技巧)。

编辑: 以下 2 sn-ps 显示了我遇到的问题。在views.py 中,我正在查询m2m 关系。

    for t in items:
          try:
              t.price = t.user_item_rel_set.get(user=u).payment_amount
          except:
              t.price = -1 * t.buyer_item_rel_set.get(buyer=u).payment_amount
    return items

另外,我的模型中的一个函数:

def listBuyers(self):
    return self.buyer_item_rel_set.all()

我有这个是因为我在我的模板中使用它来从这些元素中获取信息。

查询 m2m 关系最终会运行两次:一次在 views.py 中,然后一次在模板中。我想在视图中获取查询集,将其附加到模型实例,然后将其提供给模板,因此它(和 views.py 代码)使用缓存的查询集,而不是再次获取。

【问题讨论】:

    标签: django


    【解决方案1】:

    是的,我一直这样做。以您的 listBuyers 方法为例(顺便说一下,Pythonic 约定将其称为 list_buyers...)

    def listBuyers(self):
        if not hasattr(self, '_buyers'):
            self._buyers = self.buyer_item_rel_set.all()
        return self._buyers
    

    这将在第一次为特定实例调用 listBuyers 时访问数据库,但之后不会。

    【讨论】:

    • 但在这种情况下,'self' 指的是 Django 模型,所以我不能向它附加东西。
    • 为什么不呢?当然可以。您可以将任何您喜欢的内容附加到任何 Python 对象。 (当然,self 指的是实例,而不是模型。)
    • 一个简单的测试:x = Item.objects.all()[0] x._test = 'aoeu' print x._test 上面会失败。
    • 我相信实际上应该是if not hasattr(self, '_buyers'): hasattr 的第二个参数是一个字符串。
    • 请求范围结束时如何使缓存值过期?
    【解决方案2】:

    查询已被缓存。有关在页面加载期间生成的 how to view SQL queries 的信息,请参阅 Django FAQ

    问题可能很简单,例如缺少索引(尽管 Django 的 ORM 应该生成所需的索引)或使用 QuerySet 的结果的代码效率低下。我们需要更多信息来帮助解决问题。

    【讨论】:

    • 在上面编辑以显示查询很多的代码。由于后来调用了该 m2m 关系,它再次多次访问数据库。
    【解决方案3】:

    很难说没有看到您的模型及其关系(例如,“t”与用户“u”的关系如何)

    但是建议在一次查询中被击中所有与用户('u')项目相关的内容,而不是一个接一个地计算所需的东西......

    顺便说一句.. 't' 和 'u' 不是很好的变量名称

    【讨论】:

      猜你喜欢
      • 2021-03-06
      • 2013-08-02
      • 2014-06-06
      • 2021-08-19
      • 2013-05-20
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      相关资源
      最近更新 更多