mirror of
https://github.com/Hopiu/django-notifications.git
synced 2026-05-23 19:55:51 +00:00
Fix #69
This commit is contained in:
parent
596b0fd02b
commit
de6d41818b
6 changed files with 62 additions and 44 deletions
16
README.rst
16
README.rst
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
16
notifications/settings.py
Normal 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
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue