简体   繁体   English

在 Django 中的 QuerySet 级别缓存

[英]Caching at QuerySet level in Django

I'm trying to get a queryset from the cache, but am unsure if this even has a point.我正在尝试从缓存中获取查询集,但不确定这是否有意义。

I have the following method (simplified) inside a custom queryset :我在自定义查询集中有以下方法(简化):

    def queryset_from_cache(self, key: str=None, timeout: int=60):
        # Generate a key based on the query.
        if key is None:
            key = self.__generate_key # ()

        # If the cache has the key, return the cached object.
        cached_object = cache.get(key, None)

        # If the cache doesn't have the key, set the cache, 
        # and then return self (from DB) as cached_object
        if cached_object is None:
            cached_object = self
            cache.set(key, cached_object , timeout=timeout)

        return cached_object

The usage is basically to append it to a django QuerySet method, for example:用法基本上是对 append 它的一个 django QuerySet 方法,例如:

queryset = MyModel.objects.filter(id__range=[0,99]).queryset_from_cache()

My question:我的问题:

Would usage like this work?这样的用法会起作用吗?

Or would it call MyModel.objects.filter(id__range=[0,99]) from the database no matter what?还是无论如何都会从数据库中调用MyModel.objects.filter(id__range=[0,99])


Since normally caching would be done like this:因为通常缓存会这样完成:
cached_object = cache.get(key, None)

if cached_object is None:
    cached_object = MyModel.objects.filter(id__range=[0,99])
    #Only now call the query
    cache.set(key, cached_object , timeout=timeout)

And thus the queryset filter() method only gets called when the key is not present in the cache, as opposed to always calling it, and then trying to get it from the cache with the queryset_from_cache method.因此,queryset filter()方法仅在缓存中不存在密钥时才被调用,而不是始终调用它,然后尝试使用queryset_from_cache方法从缓存中获取它。

This is a really cool idea, but I'm not sure if you can Cache full-on Objects.. I think it's only attributes这是一个非常酷的想法,但我不确定你是否可以缓存完整的对象。我认为这只是属性

Now this having a point.现在这有一点。 Grom what I'm seeing from the limited code I've seen idk if it does have a point, unless filtering for Jane and John (and only them) is very common. Grom 我从我看到的有限代码中看到的 idk 如果它确实有一点,除非过滤 Jane 和 John(并且只有他们)非常常见。 Very narrow . Maybe just try caching ALL the users or just individual Users, and only the attributes you need也许只是尝试缓存所有用户或单个用户,并且只缓存您需要的属性


Update更新

Yes, you are completetly correct, you can cache full on objects- how cool!是的,你是完全正确的,你可以在对象上缓存满 - 太酷了!

I don't think your example method of queryset = MyModel.objects.filter(id__range=[0,99]).queryset_from_cache() would work.我认为您的queryset = MyModel.objects.filter(id__range=[0,99]).queryset_from_cache()示例方法不起作用。

but you can do something similar by using Model Managers and do something like: queryset = MyModel.objects.queryset_from_cache(filterdict)但是您可以使用 Model 管理器执行类似的操作,并执行以下操作: queryset = MyModel.objects.queryset_from_cache(filterdict)

Models楷模

  • Natually you can return just the qs, this is just for the example to show it actually is from the cache当然,您可以返回 qs,这只是为了显示它实际上来自缓存的示例
from django.db import models

class MyModelManager(models.Manager):
  def queryset_from_cache(self, filterdict):
    from django.core.cache import cache

    cachekey = 'MyModelCache'
    qs = cache.get(cachekey)

    if qs:
      d = {
        'in_cache': True,
        'qs': qs
        }
    else:
      qs = MyModel.objects.filter(**filterdict)
      cache.set(cachekey, qs, 300) # 5 min cache
      d = {
        'in_cache': False,
        'qs': qs
        }
    return d


class MyModel(models.Model):
  name    =   models.CharField(max_length=200)
  #
  # other attributes
  #

  objects = MyModelManager()

Example Use示例使用

from app.models import MyModel
filterdict = {'pk__range':[0,99]}
r = MyModel.objects.queryset_from_cache(filterdict)
print(r['qs'])

While it's not exactly what you wanted, it might be close enough虽然它不完全是您想要的,但它可能已经足够接近了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM