且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

向django模型添加迷你高速缓存

更新时间:2023-12-06 13:47:40

是的,我一直都这样做。使用listBuyers方法作为示例(顺便说一下,Pythonic约定将被称为 list_buyers ...)

  def listBuyers(self):
如果不是hasattr(self,'_buyers'):
self._buyers = self.buyer_item_rel_set.all()
return self._buyers

这将在第一次针对特定实例调用listBuyers时触发数据库,但不是之后。


I'm running into performance issues with Django because of m2m relationships. I have a list of Something objects that all have Something_instance.item_set, so I call Something_instance.item_set.all() many times. I'd like to cache that query into Something_instance so that I don't have to run so many queries. Is this possible? (This is essentially a hack for getting select_related() to work for m2m).

EDIT: The following 2 snippets shows the problem I'm having. In views.py, I'm querying the m2m relationship.

    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

Also, a function in my model:

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

I have this because I use it in my template to get information from those elements.

Querying the m2m relationships end up running twice: once in the views.py, and then once in the template. I'd like to get the queryset in views, attach it to the model instance, and then feed that to the template, so it (and the views.py code) uses the cached queryset, instead of fetching again.

Yes, I do this all the time. Using your listBuyers method as an example (by the way, Pythonic convention would be to call it list_buyers...)

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

This will hit the database the first time listBuyers is called for a particular instance, but not afterwards.