我正在尝试为django消息做一个简单的推送协议。因此,在我的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循环什么也不做,因为消息框架只是简单地重新读取会话变量,该会话变量仅在新请求上“更新”。
我尝试查看底层代码,以查看是否有任何有关动态更新存储的内容,但至少在消息传递框架中,似乎没有任何代码可以做到这一点。有storage.update()
一种很有前途的未记录方法,但事实证明它还有其他用途。
那么,Django框架中是否有任何东西可以让我轮询任何消息更改,并在发生更改时向浏览器报告?还是可以更优雅地实现同一目标的其他方法?
通过一些警告,我设法找到了可以接受的解决方案。事实证明,使用现有的消息存储(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]
请注意,从内部看,这仍然是一种轮询解决方案(循环不断地重新加载消息),但是它证明了这一概念并最终起作用。任何潜在的存储/信号机制优化都超出了此答案的范围。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句