This commit is contained in:
Alvaro Leonel 2018-05-30 02:18:33 -03:00
parent 596b0fd02b
commit de6d41818b
6 changed files with 62 additions and 44 deletions

View file

@ -123,7 +123,7 @@ Extra data
You can attach arbitrary data to your notifications by doing the following:
* Add to your settings.py: ``NOTIFICATIONS_USE_JSONFIELD=True``
* Add to your settings.py: ``DJANGO_NOTIFICATION_CONFIG = { 'USE_JSONFIELD': True}``
Then, any extra arguments you pass to ``notify.send(...)`` will be attached to the ``.data`` attribute of the notification object.
These will be serialised using the JSONField's serialiser, so you may need to take that into account: using only objects that will be serialised is a good idea.
@ -134,7 +134,7 @@ Soft delete
By default, ``delete/(?P<slug>\d+)/`` deletes specified notification record from DB.
You can change this behaviour to "mark ``Notification.deleted`` field as ``True``" by:
* Add to your settings.py: ``NOTIFICATIONS_SOFT_DELETE=True``
* Add to your settings.py: ``DJANGO_NOTIFICATION_CONFIG = { 'SOFT_DELETE': True}``
With this option, QuerySet methods ``unread`` and ``read`` contain one more filter: ``deleted=False``.
Meanwhile, QuerySet methods ``deleted``, ``active``, ``mark_all_as_deleted``, ``mark_all_as_active`` are turned on.
@ -171,13 +171,13 @@ Return all of the sent notifications, filtering the current queryset. (emailed=T
~~~~~~~~~~~~~~~
Return all of the unread notifications, filtering the current queryset.
When ``NOTIFICATIONS_SOFT_DELETE=True``, this filter contains ``deleted=False``.
When ``SOFT_DELETE=True``, this filter contains ``deleted=False``.
``qs.read()``
~~~~~~~~~~~~~~~
Return all of the read notifications, filtering the current queryset.
When ``NOTIFICATIONS_SOFT_DELETE=True``, this filter contains ``deleted=False``.
When ``SOFT_DELETE=True``, this filter contains ``deleted=False``.
``qs.mark_all_as_read()`` | ``qs.mark_all_as_read(recipient)``
@ -206,25 +206,25 @@ Mark all of the sent notifications in the queryset (optionally also filtered by
~~~~~~~~~~~~~~~~
Return all notifications that have ``deleted=True``, filtering the current queryset.
Must be used with ``NOTIFICATIONS_SOFT_DELETE=True``.
Must be used with ``SOFT_DELETE=True``.
``qs.active()``
~~~~~~~~~~~~~~~
Return all notifications that have ``deleted=False``, filtering the current queryset.
Must be used with ``NOTIFICATIONS_SOFT_DELETE=True``.
Must be used with ``DELETE=True``.
``qs.mark_all_as_deleted()`` | ``qs.mark_all_as_deleted(recipient)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark all notifications in the queryset (optionally also filtered by ``recipient``) as ``deleted=True``.
Must be used with ``NOTIFICATIONS_SOFT_DELETE=True``.
Must be used with ``DELETE=True``.
``qs.mark_all_as_active()`` | ``qs.mark_all_as_active(recipient)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark all notifications in the queryset (optionally also filtered by ``recipient``) as ``deleted=False``.
Must be used with ``NOTIFICATIONS_SOFT_DELETE=True``.
Must be used with ``SOFT_DELETE=True``.
Model methods

View file

@ -1,39 +1,34 @@
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django import get_version
from django.utils import timezone
from distutils.version import StrictVersion
from django import get_version
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.db.models.query import QuerySet
from django.utils import timezone
from django.utils.six import text_type
from jsonfield.fields import JSONField
from model_utils import Choices
from notifications import settings as notifications_settings
from notifications.signals import notify
from notifications.utils import id2slug
if StrictVersion(get_version()) >= StrictVersion('1.8.0'):
from django.contrib.contenttypes.fields import GenericForeignKey
else:
from django.contrib.contenttypes.generic import GenericForeignKey
from django.db import models
from django.db.models.query import QuerySet
from django.core.exceptions import ImproperlyConfigured
from django.utils.six import text_type
from .utils import id2slug
from .signals import notify
from model_utils import Choices
from jsonfield.fields import JSONField
from django.contrib.auth.models import Group
# SOFT_DELETE = getattr(settings, 'NOTIFICATIONS_SOFT_DELETE', False)
def is_soft_delete():
# TODO: SOFT_DELETE = getattr(settings, ...) doesn't work with "override_settings" decorator in unittest
# But is_soft_delete is neither a very elegant way. Should try to find better approach
return getattr(settings, 'NOTIFICATIONS_SOFT_DELETE', False)
return notifications_settings.get_config()['SOFT_DELETE']
def assert_soft_delete():
if not is_soft_delete():
msg = """To use 'deleted' field, please set 'NOTIFICATIONS_SOFT_DELETE'=True in settings.
msg = """To use 'deleted' field, please set 'SOFT_DELETE'=True in settings.
Otherwise NotificationQuerySet.unread and NotificationQuerySet.read do NOT filter by 'deleted' field.
"""
raise ImproperlyConfigured(msg)
@ -242,9 +237,7 @@ class Notification(models.Model):
self.unread = True
self.save()
# 'NOTIFY_USE_JSONFIELD' is for backward compatibility
# As app name is 'notifications', let's use 'NOTIFICATIONS' consistently from now
EXTRA_DATA = getattr(settings, 'NOTIFY_USE_JSONFIELD', False) or getattr(settings, 'NOTIFICATIONS_USE_JSONFIELD', False)
EXTRA_DATA = notifications_settings.get_config()['USE_JSONFIELD']
def notify_handler(verb, **kwargs):

16
notifications/settings.py Normal file
View file

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from django.conf import settings
CONFIG_DEFAULTS = {
'PAGINATE_BY': 20,
'JSONFIELD': False,
'SOFT_DELETE': False
}
def get_config():
USER_CONFIG = getattr(settings, 'DJANGO_NOTIFICATION_CONFIG', {})
CONFIG = CONFIG_DEFAULTS.copy()
CONFIG.update(USER_CONFIG)
return CONFIG

View file

@ -54,7 +54,10 @@ TEMPLATES = [
},
]
NOTIFICATIONS_USE_JSONFIELD = True
LOGIN_REDIRECT_URL = 'test/'
LOGIN_URL = '/admin/login/'
APPEND_SLASH = True
DJANGO_NOTIFICATION_CONFIG = {
'USE_JSONFIELD': True,
}

View file

@ -114,7 +114,9 @@ class NotificationManagersTest(TestCase):
Notification.objects.filter(recipient=self.to_user).mark_all_as_read()
self.assertEqual(self.to_user.notifications.unread().count(), 0)
@override_settings(NOTIFICATIONS_SOFT_DELETE=True)
@override_settings(DJANGO_NOTIFICATION_CONFIG={
'SOFT_DELETE': True
})
def test_mark_all_as_read_manager_with_soft_delete(self):
# even soft-deleted notifications should be marked as read
# refer: https://github.com/django-notifications/django-notifications/issues/126
@ -138,7 +140,9 @@ class NotificationManagersTest(TestCase):
self.assertRaises(ImproperlyConfigured, Notification.objects.mark_all_as_deleted)
self.assertRaises(ImproperlyConfigured, Notification.objects.mark_all_as_active)
@override_settings(NOTIFICATIONS_SOFT_DELETE=True)
@override_settings(DJANGO_NOTIFICATION_CONFIG={
'SOFT_DELETE': True
})
def test_mark_all_deleted_manager(self):
n = Notification.objects.filter(recipient=self.to_user).first()
n.mark_as_read()
@ -246,7 +250,9 @@ class NotificationTestPages(TestCase):
self.assertEqual(len(response.context['notifications']), len(self.to_user.notifications.unread()))
self.assertEqual(len(response.context['notifications']), self.message_count-1)
@override_settings(NOTIFICATIONS_SOFT_DELETE=True)
@override_settings(DJANGO_NOTIFICATION_CONFIG={
'SOFT_DELETE': True
})
def test_soft_delete_messages_manager(self):
self.login('to', 'pwd')

View file

@ -1,16 +1,15 @@
from distutils.version import StrictVersion
from django import get_version
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.forms import model_to_dict
from django.shortcuts import get_object_or_404, redirect
from django.utils.decorators import method_decorator
from django.views.generic import ListView
from .models import Notification
from .utils import id2slug, slug2id
from notifications.models import Notification
from notifications.utils import id2slug, slug2id
from notifications import settings
if StrictVersion(get_version()) >= StrictVersion('1.7.0'):
from django.http import JsonResponse
else:
@ -30,6 +29,7 @@ else:
class NotificationViewList(ListView):
template_name = 'notifications/list.html'
context_object_name = 'notifications'
paginate_by = settings.get_config()['PAGINATE_BY']
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
@ -43,7 +43,7 @@ class AllNotificationsList(NotificationViewList):
"""
def get_queryset(self):
if getattr(settings, 'NOTIFICATIONS_SOFT_DELETE', False):
if settings.get_config()['SOFT_DELETE']:
qs = self.request.user.notifications.active()
else:
qs = self.request.user.notifications.all()
@ -106,7 +106,7 @@ def delete(request, slug=None):
notification = get_object_or_404(
Notification, recipient=request.user, id=_id)
if getattr(settings, 'NOTIFICATIONS_SOFT_DELETE', False):
if settings.get_config()['SOFT_DELETE']:
notification.deleted = True
notification.save()
else: