2016-10-03 45 views
0

我正在嘗試爲django messages做一個簡單的推送協議。所以在我的REST調用,我有以下片段:Django刷新會話以獲取用戶的任何新消息

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循環不執行任何操作,因爲消息框架簡單地重新讀取新的請求會話變量,只有「更新」。

我試着進入底層代碼,看看是否有任何關於更新存儲的動態,但似乎沒有代碼可以做到這一點,至少在消息傳遞框架中。有這種有前途的無證方法,但它原來做別的。

那麼,在Django框架中是否有任何事情可以讓我輪詢任何消息更改,並在瀏覽器報告時向瀏覽器報告?或者一種不同的方法可以更優雅地實現同一件事?

回答

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] 

請注意,在內部這仍是一個輪詢的解決方案(在循環不斷地重新加載消息),但它證明了這個概念並最終發揮作用。任何基礎的存儲/信號機制優化都超出了這個答案的範圍。