Search code examples
pythondjangodjango-signalsdjango-appsdjango-notification

How to use django-notification to inform a user when somebody comments on their post


I have been developing in django for sometime now, and have developed a neat website having functionality such as writing blogs, posting questions, sharing content etc. However there is still one thing that is missing and i.e. creating notification for users.

What I want to do is to inform users in their profiles, whenever somebody comments on their posts, or if they are following a particular post and there is an update on it, then inform the user of that update. I have looked around many applications but I am still very confused about how to do it.

In case of using django-notification I seem to have an impression(which can be wrong) that I can use this only to inform the user via email, i.e. I cannot show these notifications in the user profile, just like we have on facebook.

Firstly I would like to know if I am wrong, and then I really need some proper tutorial or guidance on how to go about doing it. I know how to register a notification and send it on proper signal but there is no documentation on how to show these notices in a template, if this can be done.

Any guidance/tutorial/getting started doc will be deeply appreciated.


Solution

  • Yes django-notifications is only designed for email notifications.

    Here is a signal slot that you can add to your models.py and tweak to your own needs:

    from django.db import models
    from django.contrib.sites.models import Site
    from django.db.models import signals
    from notification import models as notification
    
    def create_notice_types(app, created_models, verbosity, **kwargs):
        notification.create_notice_type("new_comment", "Comment posted", "A comment has been posted")
    signals.post_syncdb.connect(create_notice_types, sender=notification)
    
    def new_comment(sender, instance, created, **kwargs):
        # remove this if-block if you want notifications for comment edit too
        if not created:
            return None
    
        context = {
            'comment': instance,
            'site': Site.objects.get_current(),
        }
        recipients = []
    
        # add all users who commented the same object to recipients
        for comment in instance.__class__.objects.for_model(instance.content_object):
            if comment.user not in recipients and comment.user != instance.user:
                recipients.append(comment.user)
    
        # if the commented object is a user then notify him as well
        if isinstance(instance.content_object, models.get_model('auth', 'User')):
            # if he his the one who posts the comment then don't add him to recipients
            if instance.content_object != instance.user and instance.content_object not in recipients:
                recipients.append(instance.content_object)
    
        notification.send(recipients, 'new_comment', context)
    
    signals.post_save.connect(new_comment, sender=models.get_model('comments', 'Comment'))
    

    Now for templates, pretty easy.

    templates/notification/new_comment/short.txt

    {{ comment.user }} commented on {{ comment.object }}
    

    templates/notification/new_comment/notice.html

    <a href="{{ comment.user.get_absolute_url }}">{{ comment.user }}</a> commented <a href="{{ comment.content_object.get_absolute_url }}">{{ comment.content_object }}</a>
    

    templates/notification/new_comment/full.txt

    {{ comment.user }} commented on {{ comment.content_object }}
    
    Comment:
    {{ comment.comment }}
    
    Reply on: 
    http://{{ site.domain }}{{ comment.content_object.get_absolute_url }}
    

    Warning: it's a very simplified, untested adaptation of our production code.

    Note : Django-1.7 deprecated the post_syncdb signal

    Here are some more information: