开发者

Django - leaving messages to (offline) users using the new messages framework

So message_set is deprecated in favor of the new messages framework. The good old message_set allowed me to leave messages to offline users (for example, when I do some stuff in a cron job I may want to notify some user about that). Now take a glance at the new framework and it seems that a message can only be added to the request object.

Have I missed anything or开发者_如何学运维 is the functionality of adding a message to a user object gone, which means I'll have to roll my own?


It doesn't look like you're missing anything. The functionality of adding messages to a user object will be deprecated in Django 1.2, and removed completely in 1.4 (from the django authentication docs here). And none of the new messaging storage backends are pre-rolled for persistent (e.g. database or file storage) of messages.

But all is not lost. I see nothing in the new messaging storage backend code that insists that you provide a valid request when storing a message (so storing a message from, for instance, a cron job would work). If I were you, I would roll my own backend that stashes messages in a database table.

Edit: How you might implement this

If your ok with implementing the offline message storage as a bolt on to one of the new messaging backends one possible approach is:

  1. Define a message Model

    class UserMessage(models.Model):
      user = models.ForeignKey('auth.User')
      message = models.CharField(max_length=200)
      created = models.DateTimeField(auto_now_add=True)
    
  2. Manually create UserMessages from your cron job

    def some_func_in_my_cron_job():
      ...
      UserMessage.create(user=some_user, message="Something happened")
      ...
    
  3. Define a new message storage engine, overriding one of the existing engines, and redefine _get()

    from django.contrib.messages.storage.session import SessionStorage
    
    class MyStorageEngine(SessionStorage):
      def _get(self, *args, **kwargs):
        if hasattr(self.request, "user") and self.request.user.is_authenticated():
            offline_messages = UserMessage.objects.filter(user=self.request.user)
            # and delete the messages from the database
        else:
            offline_messages = None
    
      other_messages = super(MyStorageEngine, self)._get(*args, **kwargs)
    
      # all_messages = combine offline_messages and other_messages
    
      return all_messages
    
  4. Turn on your new message engine in settings:

    MESSAGE_STORAGE = 'myproj.custom_message_storage.MyStorageEngine'
    

With this approach, you won't write to your database backend using the new messaging api, but you can read your manually set messages with it. Hope this helps.


Someone has created a nice implementation of this, possibly based on the accepted answer:

https://github.com/dym/django-offline-messages

from offline_messages.utils import create_offline_message, constants

user = User.objects.get(pk=1)
create_offline_message(user, 'Woo, it worked', constants.SUCCESS)

The message will be displayed to the user on the next page load.


messages_extends for the django messages framework https://github.com/AliLozano/django-messages-extends/blob/master/README.md


If your settings.py is using messages_extends.storages.FallbackStorage, you can create a persistent message (will display indefinetely until the user clicks x), using:

import messages_extends
from messages_extends.models import Message
Message.objects.create(user=target_user, level=messages_extends.INFO_PERSISTENT, message='Hey! You will see me until you click X!')

Here is the definition for the Message model:

class Message(models.Model):
    user = models.ForeignKey(User, blank=True, null=True)
    message = models.TextField()
    LEVEL_CHOICES = (
        (messages_extends.DEBUG_PERSISTENT, 'PERSISTENT DEBUG'),
        (messages_extends.INFO_PERSISTENT, 'PERSISTENT INFO'),
        (messages_extends.SUCCESS_PERSISTENT, 'PERSISTENT SUCCESS'),
        (messages_extends.WARNING_PERSISTENT, 'PERSISTENT WARNING'),
        (messages_extends.ERROR_PERSISTENT, 'PERSISTENT ERROR'),
        )
    level = models.IntegerField(choices=LEVEL_CHOICES)
    extra_tags = models.CharField(max_length=128)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    read = models.BooleanField(default=False)
    expires = models.DateTimeField(null=True, blank=True)

The other storages probably just store the message in the memory, so you'd really don't have it in hand.


The docs claim there are 4 different storage engines. The FallbackStorage engine writes to the session.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜