Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

django

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?

like image 783
shanyu Avatar asked Dec 31 '09 14:12

shanyu


1 Answers

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.

like image 129
zlovelady Avatar answered Sep 28 '22 01:09

zlovelady