Last active
January 10, 2017 15:57
-
-
Save agusmakmun/6607cbd13b7e6b06a0da97cd18b2ef22 to your computer and use it in GitHub Desktop.
Django Forum Notifications Concept
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Notification(TimeStampedModel): | |
sender = models.ForeignKey(User, related_name='sender_notification') | |
receiver = models.ForeignKey(User, related_name='receiver_notification') | |
content_type = models.ForeignKey( | |
ContentType, related_name='notification', on_delete=models.CASCADE) | |
object_id = models.PositiveIntegerField() | |
STATUS_CHOICES = ( | |
('mention', _('Mention')), | |
('reply', _('Reply Comment')), | |
('first_comment', _('First Comment')) | |
) | |
status = models.CharField( | |
max_length=20, default='reply', | |
choices=STATUS_CHOICES | |
) | |
content_object = GenericForeignKey('content_type', 'object_id') | |
def __str__(self): | |
status = _('replied your comment') | |
if self.status == 'mention': | |
status = _('mentioned you') | |
elif self.status == 'first_comment': | |
status = _('posted comment') | |
return _('%(username)s %(status)s on %(content_object)s at %(time)s') % { | |
'username': self.user.username, | |
'status': status, | |
'content_object': self.content_object, | |
'created': self.created | |
} | |
def get_related_object(self): | |
""" | |
return the related object of content_type. | |
eg: <Thread: Holisticly grow synergistic best practices> | |
""" | |
# This should return an error: MultipleObjectsReturned | |
# return self.content_type.get_object_for_this_type() | |
# So, i handle it with this one: | |
model_class = self.content_type.model_class() | |
return model_class.objects.get(id=self.object_id) | |
def get_model_name(self): | |
""" | |
return lowercase of model name. | |
eg: `thread`, `comment` | |
""" | |
return self.get_related_object()._meta.model_name | |
class Meta: | |
verbose_name = _('Detail Notification') | |
verbose_name_plural = _('Notifications') | |
ordering = ['-created'] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@login_required | |
def notifications_dashboard(request): | |
""" | |
dashboard view for all users logged in. | |
""" | |
numb_pages = 10 | |
get_page = request.GET.get('page') | |
template_name = 'app_forum/private/dashboard_notifications.html' | |
notifications = Notification.objects.filter(receiver=request.user) # here we got it by `receiver` | |
page_obj = PaginatorFBV( | |
notifications, numb_pages, get_page | |
).queryset_paginated() | |
page_range = PaginatorFBV( | |
notifications, numb_pages, get_page | |
).page_numbering() | |
notifications = page_obj.object_list | |
context = { | |
'notifications': notifications, | |
'page_obj': page_obj, | |
'page_range': page_range | |
} | |
return render(request, template_name, context) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@login_required | |
def thread_new(request, topic_slug): | |
""" | |
new thread form view. | |
:param `topic_slug` is slug for `Topic` | |
""" | |
template_name = 'app_forum/private/thread_new.html' | |
topic = get_object_or_404(Topic, slug=topic_slug) | |
if request.method == 'POST': | |
form = ThreadForm(request.POST, instance=Thread()) | |
if form.is_valid(): | |
initial = form.save(commit=False) | |
initial.author = request.user | |
# condition to set `type` of thread, `normal/pinned` | |
is_allowed = new_thread_privilege(request.user) | |
if is_allowed: | |
initial.type = request.POST.get('type') | |
else: | |
initial.type = 'normal' | |
initial.topic = topic | |
initial.save() | |
form.save() | |
# find mentions on this thread description | |
# and create a notification for users mentioned. | |
username_list = mention_finder(initial.description) # return list of `usernames` | |
for username in username_list: | |
if username != request.user.username: | |
# creating a `Notification` for the users | |
# that mentioned on this thread. | |
content_type = ContentType.objects.get(model='thread') | |
notification = Notification.objects.create( | |
sender=request.user, | |
receiver=get_object_or_404(User, username=username), | |
content_type=content_type, | |
object_id=initial.id, | |
status='mention' | |
) | |
notification.save() | |
return redirect('detail_thread_page', | |
topic_slug=topic.slug, | |
pk=initial.pk) | |
else: | |
form = ThreadForm(instance=Thread()) | |
context = {'form': form, 'topic': topic} | |
return render(request, template_name, context) | |
@login_required | |
def thread_edit(request, topic_slug, pk): | |
""" | |
edit thread form view. | |
:param `topic_slug` is topic slug. | |
:param `pk` is pk/id from the thread. | |
""" | |
template_name = 'app_forum/private/thread_edit.html' | |
thread = get_object_or_404( | |
Thread, topic__slug=topic_slug, pk=pk) | |
# Find exited users that already mentioned before. | |
# return list of `usernames` | |
users_mentioned = mention_finder(thread.description) | |
# makesure the thread is allowed to be edit. | |
is_allowed = edit_thread_privilege( | |
thread=thread, user=request.user) | |
if is_allowed == False: | |
return redirect('detail_thread_page', | |
topic_slug=topic_slug, pk=pk) | |
if request.method == 'POST': | |
form = ThreadForm(request.POST, instance=thread) | |
if form.is_valid(): | |
initial = form.save(commit=False) | |
initial.author = thread.author | |
initial.save() | |
form.save() | |
# find mentions on this thread description | |
# and create a notification for users mentioned. | |
# But, makesure the users doesn't exist at the notifications before. | |
# `users_mentioned` is list users already mentioned before. | |
username_list = mention_finder(initial.description) | |
for username in username_list: | |
if username not in users_mentioned and username != thread.author.username: | |
# creating a `Notification` for the users | |
# that mentioned on this thread. | |
content_type = ContentType.objects.get(model='thread') | |
notification = Notification.objects.create( | |
sender=thread.author, | |
receiver=get_object_or_404(User, username=username), | |
content_type=content_type, | |
object_id=thread.id, | |
status='mention' | |
) | |
notification.save() | |
return redirect('detail_thread_page', | |
topic_slug=topic_slug, pk=pk) | |
else: | |
form = ThreadForm(instance=thread) | |
context = {'form': form, 'thread': thread} | |
return render(request, template_name, context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment