如何取消缓存Django模型

如何取消缓存Django模型,django,Django,我有一个叫做Chat的模型,它可以从自身存储和检索cookie,如下所示: >>> chat = Chat.objects.get(pk=43265) >>> chat.cookies >>> chat.set_cookie('1','2') >>> chat.cookies '{"1": "2"}' set\u cookies方法通过一个简单的json.dumps实现: def set_cookie(self, key,

我有一个叫做
Chat
的模型,它可以从自身存储和检索cookie,如下所示:

>>> chat = Chat.objects.get(pk=43265)
>>> chat.cookies
>>> chat.set_cookie('1','2')
>>> chat.cookies
'{"1": "2"}'
set\u cookies
方法通过一个简单的
json.dumps实现:

def set_cookie(self, key, value):
    if self.cookies:
        current_cookies = json.loads(self.cookies)
    else:
        current_cookies = dict()
    current_cookies.update({key: value})
    self.cookies = json.dumps(current_cookies)
    self.save()
问题是,如果在两个不同的名称空间中检索到
chat
对象,它们会独立更新其cookie,每个cookie都会覆盖另一个cookie的结果

例如:

import django
django.setup()

from bots.models import Chat

# Let's clean all the cookies beforehand 
c = Chat.objects.get(pk=43265)
c.cookies = None
c.save()

def outer_namespace():
    chat = Chat.objects.get(pk=43265)

    # here chat.cookies are empty
    inner_namespace()
    # Now we are supposed to have inner cookie here - right? Let's set another one.

    chat.set_cookie('outer namespace cookie', '1')

    # Let's retrieve the model again and see
    print(Chat.objects.get(pk=43265).cookies)


def inner_namespace():
    inner_chat = Chat.objects.get(pk=43265)
    inner_chat.set_cookie('inner namespace cookie', '2')


outer_namespace()
如果我运行此命令,我将得到:

>>> {"outer namespace cookie": "1"}
>>> # we lost one of the cookies!
如何避免这种情况? 我提出的唯一解决方案是在其自己的<代码> SETIKOICE 方法中间重新检索<代码>聊天> /代码>对象。但这看起来很笨拙

def set_cookie(self, key, value):
    cookies = self.__class__.objects.get(pk=self.pk).cookies
    #
    # ... rest of the method stays the same

另一个经典的例子是为什么你应该总是规范化你的数据库。您的理想结构应该是拥有另一个聊天cookie模型

class Cookie(models.Model):
    name = models.CharField()
    value = models.CharField()
    chat = models.ForeignKey(Chat)
现在,您可以使用queryset上的
.update
方法更新字段,而无需删除其他字段。在自己的线程或其他线程中设置。您不必在每次保存之前一直重新读取数据


如果由于某些令人信服的原因,您无法将设计转换为正确的设计,您至少应该投资在cookie中使用JsonField。JSONField目前仅适用于postgresql,但也有其他数据库的第三方插件。

另一个经典例子说明了为什么您应该始终规范化数据库。您的理想结构应该是拥有另一个聊天cookie模型

class Cookie(models.Model):
    name = models.CharField()
    value = models.CharField()
    chat = models.ForeignKey(Chat)
现在,您可以使用queryset上的
.update
方法更新字段,而无需删除其他字段。在自己的线程或其他线程中设置。您不必在每次保存之前一直重新读取数据

如果由于某些令人信服的原因,您无法将设计转换为正确的设计,您至少应该投资在cookie中使用JsonField。目前,JSONField仅适用于postgresql,但其他数据库也有第三方插件