我可以将Django模型对象作为单例获得吗?

时间:2018-07-07 07:09:15

标签: python django django-models

当我用相同的ID调用Models.get()时,它将返回不同的Python对象:

print(Book.objects.get(id=1) is Book.objects.get(id=1))
>>> False

我想知道是否可以更改此行为,也许可以使用某些自定义模型管理器。它可以在内部为所有检索到的对象存储一些注册表,并覆盖get_queryset()以使其使用此注册表中的对象(如果已检索到这些对象)。

为什么有帮助

我有一个模型ServerCredentials,它存储登录名和密码。我有多个使用相同凭据进行连接的使用者。由于只允许与服务器建立一个连接,因此将临时连接信息(例如auth令牌)存储为ServerCredentials对象的字段,而不是存储在数据库中会很方便。如果模型对象可以是单例对象,则使用者只需使用ServerCredentials字段即可轻松共享身份验证令牌。没有它,我必须手动进行一些注册,但是我认为应该在ModelManager's端完成。

  1. 是否可以在ModelManager's端的注册表中缓存对象?
  2. 这是个好主意吗?
  3. 有没有实现的方法?

非常感谢!

2 个答案:

答案 0 :(得分:2)

模型的管理器是其各自类的常规实例,因此您可以实现某种注册。但是,此注册表在每个进程中都是唯一的。在生产中,您的应用通常由服务器启动多个进程来运行,例如uwsgi(甚至可以在多台计算机上运行)。

如果要在整个应用程序中提供临时数据,则可以将Django的缓存功能与内存存储(例如Memcached或Redis)一起使用。

答案 1 :(得分:0)

我认为您应该阅读一些有关apache / nginx如何处理每个请求的过程的信息,因为即使您可以使用单例模式,它也不起作用,因为对于一个不同的请求,每个进程可能同时运行多个进程并且每个进程在内存中都有自己的单例/缓存/注册表。下面介绍了实现每个进程缓存的一种方法。

我们在系统中缓存数据的方法是在类本身上使用STATIC变量来缓存数据,因为数据在每个会话中的存储情况取决于您的http服务器的配置方式(因此仅按进程进行缓存),所以缓存效果很好。 / p>

Class SomeModel(models.Model):
    CACHE_DATA = {} # you can use any other container but dicts are best if its keyable
    # write functions to populate this cache and read from this cache
    def populate_cache():
        # populate only its empty
        if SomeModel.is_cache_empty(key):
           # populate the Cache here

    def is_cache_empty(key):
        if key not in SomeModel.CACHE_DATA:
            return True
        else:
            return False


    def read_data_from_cache():
        # read based on key or some other you may use a linear search for a list e.g.

现在您可以使用此缓存读取数据,因为仅在填充缓存后才读取数据,您也可以在需要时刷新缓存。

您必须按照其他答案的建议使用内存缓存或Redis来满足您的确切需求(所有进程都使用相同的缓存)。