2👍
comment.content_object.user
is correct one. But this problem is tricki. Since comment can be attached to any model, you don’t know if this model has user
field. In many cases there can be different name of this field ie. If you have comment to article
, article can have article.author
and If you have car
model, and you are commenting it, there will be probably car.owner
. So using .user
for this purpose will not work in this cases.
My proposition to solve this problem is making list of possible roles interested in comment, and try to send message to all of them:
from django.contrib.comments.signals import comment_was_posted
if "notification" in settings.INSTALLED_APPS:
from notification import models as notification
def comment_notification(sender, comment, request, **kwargs):
subject = comment.content_object
for role in ['user', 'author', 'owner', 'creator', 'leader', 'maker', 'type any more']:
if hasattr(subject, role) and isinstance(getattr(subject, role), User):
user = getattr(subject, role)
message = comment
notification.send([user], "new_comment", {'message': message,})
comment_was_posted.connect(comment_notification)
You should also, move this list to some king of configuration:
from django.contrib.comments.signals import comment_was_posted
default_roles = ['user', 'author', 'owner']
_roles = settings.get('MYAPP_ROLES', default_roles)
if "notification" in settings.INSTALLED_APPS:
from notification import models as notification
def comment_notification(sender, comment, request, **kwargs):
subject = comment.content_object
for role in _roles:
if hasattr(subject, role) and isinstance(getattr(subject, role), User):
user = getattr(subject, role)
message = comment
notification.send([user], "new_comment", {'message': message,})
comment_was_posted.connect(comment_notification)
Another approach to this problem would be to create mechanism which translates class
to role
. But it’s much harder to get it right, so you probably don’t want to do that.