Django刷新会话以获取用户的任何新消息

时间:2016-10-03 13:35:41

标签: python django django-messages

我试图为django messages做一个简单的推送协议。所以在我的REST调用中,我有以下片段:

    storage = get_messages(self.request)
    res = dict(messages=[dict(level=item.level, message=item.message) for item in storage])

    now = monotonic()
    while not res.messages and monotonic() - now < 15:
        sleep(.5)
        res.messages = [dict(level=item.level, message=item.message) for item in storage]

当然,while循环什么也不做,因为消息框架只是重新读取会话变量,而该变量只会更新&#34;关于新请求。

我尝试进入底层代码,看看是否有任何关于动态更新存储的内容,但似乎没有代码可以做到这一点,至少在消息传递框架中。有这种有前途的无证storage.update()方法,但结果却做了别的事。

那么,Django框架中是否有任何内容可以让我对任何消息更改进行轮询并在发生时向浏览器报告?或者是一种能够更优雅地实现同样目标的不同方法?

1 个答案:

答案 0 :(得分:0)

我已经设法找到一个可接受的解决方案,但有一些注意事项。 事实证明,使用现有的消息存储(cookie或会话)要么是不可能的(cookie),要么是内部方法调用太多。设置/删除内部成员(会话)。

此解决方案使用新的消息存储库,在我的情况下是数据库存储库。

settings.py

MESSAGE_STORAGE = 'your_django_app.messages_store.SessionDBStorage'

your_django_app / messages_store.py

from django.contrib.messages.storage.session import SessionStorage
from main.models import MessagesStore, models


class SessionDBStorage(SessionStorage):
    """
    Stores messages in the database based on session id
    """

    def _get(self, *args, **kwargs):
        """
        Retrieves a list of messages from the database based on session identifier.
        """
        try:
            return self.deserialize_messages(
                MessagesStore.objects.get(pk=self.request.session.session_key).messages), True
        except models.ObjectDoesNotExist:
            return [], True

    def _store(self, messages, response, *args, **kwargs):
        """
        Stores a list of messages to the database.
        """
        if messages:
            MessagesStore.objects.update_or_create(session_key=self.request.session.session_key,
                                                   defaults={'messages': self.serialize_messages(messages)})
        else:
            MessagesStore.objects.filter(pk=self.request.session.session_key).delete()
        return []

your_django_app / rest.py

def pushed_messages():
    from time import sleep, monotonic
    # standard get messages code
    ....
    now = monotonic()
    while not res.messages and monotonic() - now < 15:
        sleep(1)
        if hasattr(storage, '_loaded_data'):  # one last hack to make storage reload messages
            delattr(storage, '_loaded_data')
        res.messages = [dict(level=item.level, message=item.message) for item in storage]

请注意,在内部这仍然是一个轮询解决方案(循环不断重新加载消息),但它证明了概念,并最终 - 工作。任何底层的存储/信号机制优化都超出了这个答案的范围。