【问题标题】:Django refresh session to obtain any new messages for userDjango刷新会话以获取用户的任何新消息
【发布时间】:2016-10-03 13:35:40
【问题描述】:

我正在尝试为django messages 做一个简单的推送协议。所以在我的 REST 调用中,我有以下 sn-p:

    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 循环什么也不做,因为消息框架只是重新读取会话变量,该变量只会在新请求时“更新”。

我尝试进入底层代码以查看是否有任何关于即时更新存储的内容,但似乎没有代码可以执行此操作,至少在消息传递框架中是这样。有一个很有前途的无证 storage.update() 方法,但结果证明它做了别的事情。

那么,在 Django 框架中是否有任何东西可以让我轮询任何消息更改并在发生时将其报告给浏览器?或者用不同的方法更优雅地实现同样的事情?

【问题讨论】:

    标签: python django django-messages


    【解决方案1】:

    我已经设法找到了一个可接受的解决方案,但有几点需要注意。 使用现有的消息存储(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]
    

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

    【讨论】:

      猜你喜欢
      • 2015-05-12
      • 2014-05-15
      • 2012-08-08
      • 2015-06-05
      • 2019-02-13
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多