tags:

views:

156

answers:

2

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?

A: 

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

Hank Gay
Yes, it writes to the session, which belongs to a "request".
shanyu
+3  A: 

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):
      _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.

zlovelady
Thanks for the answer. It should be easy to write a message storage backend. However, binding a message to a user and then displaying it when that user becomes online is complicated. Any suggestions?
shanyu
Added a possible approach as an edit to the answer.
zlovelady
Very helpful. Thanks..
shanyu