If I comment on a message with the name "a", I get a notification that I made a comment on "a", but the notification system should notify the user who created the message "a".
I have a key to what to do because I did something similar (notifying the user who commented when there is an answer to this comment), thanks to some lesson.
In models.py for notification, I have to send the correct notification and connect to it. I will write my full code, you can see the lower function for the connection, and this is the one I am having problems with.
from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.urlresolvers import reverse from django.db import models from django.contrib.auth.models import User from main.models import Post from accounts.models import MyProfile from .signals import notify # Create your models here. class NotificationQuerySet(models.query.QuerySet): def get_user(self, recipient): return self.filter(recipient=recipient) def mark_targetless(self, recipient): qs = self.unread().get_user(recipient) qs_no_target = qs.filter(target_object_id=None) if qs_no_target: qs_no_target.update(read=True) def mark_all_read(self, recipient): qs = self.unread().get_user(recipient) qs.update(read=True) def mark_all_unread(self, recipient): qs = self.read().get_user(recipient) qs.update(read=False) def unread(self): return self.filter(read=False) def read(self): return self.filter(read=True) def recent(self): return self.unread()[:5] class NotificationManager(models.Manager): def get_queryset(self): return NotificationQuerySet(self.model, using=self._db) def all_unread(self, user): return self.get_queryset().get_user(user).unread() def all_read(self, user): return self.get_queryset().get_user(user).read() def all_for_user(self, user): self.get_queryset().mark_targetless(user) return self.get_queryset().get_user(user) class Notification(models.Model): sender_content_type = models.ForeignKey(ContentType, related_name='nofity_sender') sender_object_id = models.PositiveIntegerField() sender_object = GenericForeignKey("sender_content_type", "sender_object_id") verb = models.CharField(max_length=255) action_content_type = models.ForeignKey(ContentType, related_name='notify_action', null=True, blank=True) action_object_id = models.PositiveIntegerField(null=True, blank=True) action_object = GenericForeignKey("action_content_type", "action_object_id") target_content_type = models.ForeignKey(ContentType, related_name='notify_target', null=True, blank=True) target_object_id = models.PositiveIntegerField(null=True, blank=True) target_object = GenericForeignKey("target_content_type", "target_object_id") recipient = models.ForeignKey(settings.AUTH_PROFILE_MODULE, related_name='notifications') read = models.BooleanField(default=False) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) objects = NotificationManager() def __unicode__(self): try: target_url = self.target_object.get_absolute_url() except: target_url = None context = { "sender": self.sender_object, "verb": self.verb, "action": self.action_object, "target": self.target_object, "verify_read": reverse("notifications_read", kwargs={"id": self.id}), "target_url": target_url, } if self.target_object: if self.action_object and target_url: return "%(sender)s %(verb)s <a href='%(verify_read)s?next=%(target_url)s'>%(target)s</a> with %(action)s" %context if self.action_object and not target_url: return "%(sender)s %(verb)s %(target)s with %(action)s" %context return "%(sender)s %(verb)s %(target)s" %context return "%(sender)s %(verb)s" %context @property def get_link(self): try: target_url = self.target_object.get_absolute_url() except: target_url = reverse("notifications_all") context = { "sender": self.sender_object, "verb": self.verb, "action": self.action_object, "target": self.target_object, "verify_read": reverse("notifications_read", kwargs={"id": self.id}), "target_url": target_url, } if self.target_object: return "<a href='%(verify_read)s?next=%(target_url)s'>%(sender)s %(verb)s %(target)s with %(action)s</a>" %context else: return "<a href='%(verify_read)s?next=%(target_url)s'>%(sender)s %(verb)s</a>" %context def new_notification(sender, **kwargs): kwargs.pop('signal', None) recipient = kwargs.pop("recipient") verb = kwargs.pop("verb") affected_users = kwargs.pop('affected_users') #super_user_qs = MyProfile.objects.get(user=Post.moderator), ''' this is wrong, It;s what I tried but failed if super_user_qs: super_user_instance = super_user_qs new_note = Notification( recipient=super_user_instance, verb = verb, # smart_text sender_content_type = ContentType.objects.get_for_model(sender), sender_object_id = sender.id, ) for option in ("target", "action"): obj = kwargs.pop(option, None) if obj is not None: setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj)) setattr(new_note, "%s_object_id" %option, obj.id) new_note.save() the below works for notifying commentor who gets reply ''' if affected_users is not None: for u in affected_users: if u == sender: pass else: new_note = Notification( recipient=recipient, verb = verb, # smart_text sender_content_type = ContentType.objects.get_for_model(sender), sender_object_id = sender.id, ) for option in ("target", "action"): try: obj = kwargs[option] if obj is not None: setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj)) setattr(new_note, "%s_object_id" %option, obj.id) except: pass new_note.save() else: new_note = Notification( recipient=recipient, verb = verb, # smart_text sender_content_type = ContentType.objects.get_for_model(sender), sender_object_id = sender.id, ) for option in ("target", "action"): obj = kwargs.pop(option, None) if obj is not None: setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj)) setattr(new_note, "%s_object_id" %option, obj.id) new_note.save() notify.connect(new_notification)
And then in models.py I have comments and publications. get_affected_user is a function that is used in comment views.py to notify affected_user. (I followed the tutorial.)
class Comment(models.Model): user = models.ForeignKey(MyProfile) parent = models.ForeignKey("self", null=True, blank=True) post = models.ForeignKey(Post, null=True, blank=True, related_name="commented_post") @property def get_origin(self): return self.path @property def get_comment(self): return self.text @property def is_child(self): if self.parent is not None: return True else: return False def get_children(self): if self.is_child: return None else: return Comment.objects.filter(parent=self) def get_affected_users(self): """ it needs to be a parent and have children, the children, in effect, are the affected users. """ comment_children = self.get_children() if comment_children is not None: users = [] for comment in comment_children: if comment.user in users: pass else: users.append(comment.user) return users return None class Post(models.Model): title = models.CharField(max_length = 50) moderator = models.ForeignKey(User) views = models.IntegerField(default=0)
In views.py for comments, the above get_affected_user is used to notify the commentator who receives the response. I was thinking of using the same function to achieve what I want, but could not. Therefore, for this I just have not set get_affected_user yet.
def comment_create_view(request): if request.method == "POST" and request.user.is_authenticated(): parent_id = request.POST.get('parent_id') post_id = request.POST.get("post_id") origin_path = request.POST.get("origin_path") try: post = Post.objects.get(id=post_id) except: post = None parent_comment = None if parent_id is not None: try: parent_comment = Comment.objects.get(id=parent_id) except: parent_comment = None if parent_comment is not None and parent_comment.post is not None: post = parent_comment.post form = CommentForm(request.POST) if form.is_valid(): comment_text = form.cleaned_data['comment'] if parent_comment is not None:
Edit: I have this problem for almost a week ... I asked the teacher for help from a textbook that I bought, and he answers only with short sentences (I can say that he is not absolutely leaving). Here are a few hints he threw. If I had to notify the superuser I should add the following to models.py for notification,
super_user_qs = User.objects.filter(is_admin=True) if super_user_qs.exists(): super_user_instance = super_user_qs.first() new_note = Notification( recipient=super_user_instance, verb = verb, # smart_text sender_content_type = ContentType.objects.get_for_model(sender), sender_object_id = sender.id, ) for option in ("target", "action"): obj = kwargs.pop(option, None) if obj is not None: setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj)) setattr(new_note, "%s_object_id" %option, obj.id) new_note.save()
but then I told him that I was trying to notify the creator of the message / moderator, because anyone can make a message. (I told him a couple of times / before he answered as superuser), I have to use the post_save model signal to create a new notification in the model I'm working on. and in this case I do not need to use a custom notification signal.
Meanwhile, I watched the textbooks again and again. I thought maybe I just need to change the recipient = MyProfile.objects.get (user = post.moderator) to post.moderator, but then I get I canβt assign ":" Notification.recipient "must be an instance of" MyProfile " .so I did recipient = MyProfile.objects.get (user = post.moderator), but that will inform me of the comments I am making ...
I'm really looking forward to any advice thanks