Thursday, November 15, 2007

Quick and dirty 'type' for Django's message model

In an earlier post I had mentioned using a 'flash' variable passed to templates as a mechanism for passing messages to users. Following an anonymous tip I started using user.message_set instead to pass messages. This mechanism makes use of Django's message model and is easy to use. However it does have a limitation. Messages cannot be assigned types - say, 'Error' or 'Success' or 'Warning'. This has been discussed at some length at the Django site. A design decision is awaited as the suggested changes will not be backward compatible.

In the meantime I needed message types for a pet application and came up with a quick and dirty way of providing some. Changes were required in three places: the view, where messages are created; the template which displays the messages and the style sheet used for styling the rendered templates.

The solution (did I say it was dirty?) involved prefixing a digit and a separator to all messages. The digit would indicate the type of message. I chose 0 to indicate success, 1 for warnings, 2 for errors etc. Corresponding styles were then created to appropriately style the messages.

Here is a sample view:
  1. def save_something(request):  
  2.     if saved:  
  3.         request.user.message_set.create(message = "0|Object was saved successfully")  
  4.     else:  
  5.         request.user.message_set.create(message = "2|Object could not be saved")  
The template looks something like this:
  1. {% if messages %}  
  2.     <div id="messages">  
  3.     {% for message in messages %}  
  4.         <p class="m{{ message|slice:"0:1"}}">{{ message|slice:"2:" }}</p>  
  5.     {% endfor %}  
  6.     </div>  
  7. {% endif %}  
There is a corresponding style sheet as well:
  1. #messages p {  
  2.   margin: 0; padding: 0;  
  3. }  
  4.   
  5. #messages p.m0 {  
  6.   backgroundtransparent url(success.gif) 0 100% no-repeat;  
  7.   colorgreen;  
  8. }  
  9.   
  10. #messages p.m1 {  
  11.   backgroundtransparent url(warning.gif) 0 100% no-repeat;  
  12.   coloryellow;  
  13. }  
  14.   
  15. #messages p.m2 {  
  16.   backgroundtransparent url(failure.gif) 0 100% no-repeat;  
  17.   colorred;  
  18. }  
  19. /* etc */