django-notifications-x 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_notifications_x-0.1.1/.gitignore +15 -0
- django_notifications_x-0.1.1/AUTHORS.txt +30 -0
- django_notifications_x-0.1.1/CHANGELOG.md +10 -0
- django_notifications_x-0.1.1/LICENSE.txt +30 -0
- django_notifications_x-0.1.1/PKG-INFO +540 -0
- django_notifications_x-0.1.1/README.md +503 -0
- django_notifications_x-0.1.1/notifications/__init__.py +13 -0
- django_notifications_x-0.1.1/notifications/admin.py +28 -0
- django_notifications_x-0.1.1/notifications/apps.py +16 -0
- django_notifications_x-0.1.1/notifications/base/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/base/admin.py +12 -0
- django_notifications_x-0.1.1/notifications/base/models.py +378 -0
- django_notifications_x-0.1.1/notifications/helpers.py +59 -0
- django_notifications_x-0.1.1/notifications/locale/id/LC_MESSAGES/django.mo +0 -0
- django_notifications_x-0.1.1/notifications/locale/id/LC_MESSAGES/django.po +127 -0
- django_notifications_x-0.1.1/notifications/locale/ru/LC_MESSAGES/django.mo +0 -0
- django_notifications_x-0.1.1/notifications/locale/ru/LC_MESSAGES/django.po +122 -0
- django_notifications_x-0.1.1/notifications/migrations/0001_initial.py +40 -0
- django_notifications_x-0.1.1/notifications/migrations/0002_auto_20150224_1134.py +24 -0
- django_notifications_x-0.1.1/notifications/migrations/0003_notification_data.py +19 -0
- django_notifications_x-0.1.1/notifications/migrations/0004_auto_20150826_1508.py +18 -0
- django_notifications_x-0.1.1/notifications/migrations/0005_auto_20160504_1520.py +18 -0
- django_notifications_x-0.1.1/notifications/migrations/0006_indexes.py +33 -0
- django_notifications_x-0.1.1/notifications/migrations/0007_add_timestamp_index.py +19 -0
- django_notifications_x-0.1.1/notifications/migrations/0008_index_together_recipient_unread.py +19 -0
- django_notifications_x-0.1.1/notifications/migrations/0009_alter_notification_options_and_more.py +162 -0
- django_notifications_x-0.1.1/notifications/migrations/0010_rename_notification_recipient_unread_notificatio_recipie_8bedf2_idx.py +17 -0
- django_notifications_x-0.1.1/notifications/migrations/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/models.py +23 -0
- django_notifications_x-0.1.1/notifications/settings.py +21 -0
- django_notifications_x-0.1.1/notifications/signals.py +5 -0
- django_notifications_x-0.1.1/notifications/static/notifications/notify.js +92 -0
- django_notifications_x-0.1.1/notifications/templates/notifications/list.html +5 -0
- django_notifications_x-0.1.1/notifications/templates/notifications/notice.html +24 -0
- django_notifications_x-0.1.1/notifications/templates/notifications/test_tags.html +8 -0
- django_notifications_x-0.1.1/notifications/templatetags/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/templatetags/notifications_tags.py +132 -0
- django_notifications_x-0.1.1/notifications/tests/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/__init__.py +1 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/admin.py +10 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/apps.py +6 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/migrations/0001_initial.py +48 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/migrations/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/models.py +9 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/templatetags/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/templatetags/notifications_tags.py +1 -0
- django_notifications_x-0.1.1/notifications/tests/sample_notifications/tests.py +46 -0
- django_notifications_x-0.1.1/notifications/tests/settings.py +85 -0
- django_notifications_x-0.1.1/notifications/tests/static/notifications/live-test.js +7 -0
- django_notifications_x-0.1.1/notifications/tests/templates/test_live.html +10 -0
- django_notifications_x-0.1.1/notifications/tests/test_models/migrations/0001_initial.py +47 -0
- django_notifications_x-0.1.1/notifications/tests/test_models/migrations/__init__.py +0 -0
- django_notifications_x-0.1.1/notifications/tests/test_models/models.py +17 -0
- django_notifications_x-0.1.1/notifications/tests/tests.py +598 -0
- django_notifications_x-0.1.1/notifications/tests/urls.py +43 -0
- django_notifications_x-0.1.1/notifications/tests/views.py +31 -0
- django_notifications_x-0.1.1/notifications/urls.py +29 -0
- django_notifications_x-0.1.1/notifications/utils.py +15 -0
- django_notifications_x-0.1.1/notifications/views.py +214 -0
- django_notifications_x-0.1.1/pyproject.toml +96 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Justin Quick <justquick@gmail.com>
|
|
2
|
+
Aaron Williamson
|
|
3
|
+
Jordan Reiter
|
|
4
|
+
Manuel Aristaran
|
|
5
|
+
Darrell Hoy
|
|
6
|
+
Ken "Elf" Mathieu Sternberg
|
|
7
|
+
Josh Ourisman
|
|
8
|
+
Trever Shick
|
|
9
|
+
Sandip Agrawal
|
|
10
|
+
Piet Delport
|
|
11
|
+
Steve Ivy
|
|
12
|
+
Ben Slavin
|
|
13
|
+
Jason Culverhouse
|
|
14
|
+
Dave Harrington
|
|
15
|
+
Pedro Bur—n
|
|
16
|
+
Ryan Quigley
|
|
17
|
+
Neelesh Shastry
|
|
18
|
+
David Gouldin <david@gould.in>
|
|
19
|
+
Donald Stufft
|
|
20
|
+
Nolan Brubaker
|
|
21
|
+
Herman Schaaf
|
|
22
|
+
Walter Scheper
|
|
23
|
+
Chris Beaven
|
|
24
|
+
Vineet Naik
|
|
25
|
+
Walter Scheper
|
|
26
|
+
Brant Young
|
|
27
|
+
Matthew Schinckel <matt@schinckel.net>
|
|
28
|
+
Mirat Can Bayrak
|
|
29
|
+
Konrad Hałas
|
|
30
|
+
Peppe Bergqvist
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Copyright (c) 2011, Justin Quick
|
|
2
|
+
Copyright (c) 2015, django-notifications team
|
|
3
|
+
Copyright (c) 2026, Panov Yury
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are
|
|
8
|
+
met:
|
|
9
|
+
|
|
10
|
+
* Redistributions of source code must retain the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer.
|
|
12
|
+
* Redistributions in binary form must reproduce the above
|
|
13
|
+
copyright notice, this list of conditions and the following
|
|
14
|
+
disclaimer in the documentation and/or other materials provided
|
|
15
|
+
with the distribution.
|
|
16
|
+
* Neither the name of the author nor the names of other
|
|
17
|
+
contributors may be used to endorse or promote products derived
|
|
18
|
+
from this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
21
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
24
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
25
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
26
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
28
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
29
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-notifications-x
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: GitHub notifications alike app for Django.
|
|
5
|
+
Project-URL: Homepage, https://github.com/PanovYury/django-notifications
|
|
6
|
+
Author: Aaron Williamson, Jordan Reiter, Manuel Aristaran, Darrell Hoy, Ken "Elf" Mathieu Sternberg, Josh Ourisman, Trever Shick, Sandip Agrawal, Piet Delport, Steve Ivy, Ben Slavin, Jason Culverhouse, Dave Harrington, Pedro Bur—n, Ryan Quigley, Neelesh Shastry, Donald Stufft, Nolan Brubaker, Herman Schaaf, Walter Scheper, Chris Beaven, Vineet Naik, Walter Scheper, Brant Young, Mirat Can Bayrak, Konrad Hałas, Peppe Bergqvist
|
|
7
|
+
Author-email: Justin Quick <justquick@gmail.com>, David Gouldin <david@gould.in>, Matthew Schinckel <matt@schinckel.net>
|
|
8
|
+
Maintainer: Panov Yury
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: AUTHORS.txt
|
|
11
|
+
License-File: LICENSE.txt
|
|
12
|
+
Keywords: action,django,event,github,notifications,stream
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Framework :: Django
|
|
16
|
+
Classifier: Framework :: Django :: 4.2
|
|
17
|
+
Classifier: Framework :: Django :: 5.0
|
|
18
|
+
Classifier: Framework :: Django :: 5.1
|
|
19
|
+
Classifier: Framework :: Django :: 5.2
|
|
20
|
+
Classifier: Intended Audience :: Developers
|
|
21
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Programming Language :: Python
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
30
|
+
Classifier: Topic :: Utilities
|
|
31
|
+
Requires-Dist: django-model-utils>=3.1.0
|
|
32
|
+
Requires-Dist: django<5.3,>=4.2
|
|
33
|
+
Requires-Dist: jsonfield>=2.1.0
|
|
34
|
+
Requires-Dist: packaging
|
|
35
|
+
Requires-Dist: swapper
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# `django-notifications` Documentation
|
|
39
|
+
|
|
40
|
+
[//]: # (TODO: Implement for the current repository)
|
|
41
|
+
[//]: # ([](https://travis-ci.org/django-notifications/django-notifications))
|
|
42
|
+
[//]: # ([](https://coveralls.io/github/django-notifications/django-notifications?branch=master))
|
|
43
|
+
|
|
44
|
+
> 🔀 This is a fork of [original](https://github.com/django-notifications/django-notifications)
|
|
45
|
+
|
|
46
|
+
[django-notifications](https://github.com/PanovYury/django-notifications) is a GitHub notification alike app for Django, it was derived from [django-activity-stream](https://github.com/justquick/django-activity-stream)
|
|
47
|
+
|
|
48
|
+
The major difference between `django-notifications` and `django-activity-stream`:
|
|
49
|
+
|
|
50
|
+
- `django-notifications` is for building something like Github "Notifications"
|
|
51
|
+
- While `django-activity-stream` is for building Github "News Feed"
|
|
52
|
+
|
|
53
|
+
Notifications are actually actions events, which are categorized by four main components.
|
|
54
|
+
|
|
55
|
+
- `Actor`. The object that performed the activity.
|
|
56
|
+
- `Verb`. The verb phrase that identifies the action of the activity.
|
|
57
|
+
- `Action Object`. *(Optional)* The object linked to the action
|
|
58
|
+
itself.
|
|
59
|
+
- `Target`. *(Optional)* The object to which the activity was
|
|
60
|
+
performed.
|
|
61
|
+
|
|
62
|
+
`Actor`, `Action Object` and `Target` are `GenericForeignKeys` to any
|
|
63
|
+
arbitrary Django object. An action is a description of an action that
|
|
64
|
+
was performed (`Verb`) at some instant in time by some `Actor` on some
|
|
65
|
+
optional `Target` that results in an `Action Object` getting
|
|
66
|
+
created/updated/deleted.
|
|
67
|
+
|
|
68
|
+
For example: [justquick](https://github.com/justquick/) `(actor)`
|
|
69
|
+
*closed* `(verb)` [issue
|
|
70
|
+
2](https://github.com/justquick/django-activity-stream/issues/2)
|
|
71
|
+
`(action_object)` on
|
|
72
|
+
[activity-stream](https://github.com/justquick/django-activity-stream/)
|
|
73
|
+
`(target)` 12 hours ago
|
|
74
|
+
|
|
75
|
+
Nomenclature of this specification is based on the Activity Streams
|
|
76
|
+
Spec: <http://activitystrea.ms/specs/atom/1.0/>
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
- Python 3.9, 3.10, 3.11, 3.12, 3.13
|
|
81
|
+
- Django 4.2, 5.1, 5.2
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
Installation is easy using `pip` and will install all required
|
|
86
|
+
libraries.
|
|
87
|
+
```bash
|
|
88
|
+
$ pip install django-notifications-x
|
|
89
|
+
```
|
|
90
|
+
or get it from source
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
$ git clone https://github.com/PanovYury/django-notifications
|
|
94
|
+
$ cd django-notifications
|
|
95
|
+
$ python setup.py bdist_wheel
|
|
96
|
+
$ pip install dist/django_notifications_x*
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Note that [django-model-utils](http://pypi.python.org/pypi/django-model-utils)
|
|
100
|
+
will be installed: this is required for the pass-through QuerySet manager.
|
|
101
|
+
|
|
102
|
+
Then to add the Django Notifications to your project add the app
|
|
103
|
+
`notifications` to your `INSTALLED_APPS` and urlconf.
|
|
104
|
+
|
|
105
|
+
The app should go somewhere after all the apps that are going to be
|
|
106
|
+
generating notifications like `django.contrib.auth`
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
INSTALLED_APPS = (
|
|
110
|
+
'django.contrib.auth',
|
|
111
|
+
...
|
|
112
|
+
'notifications',
|
|
113
|
+
...
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Add the notifications urls to your urlconf:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
urlpatterns = [
|
|
121
|
+
...
|
|
122
|
+
path('inbox/notifications/', include('notifications.urls', namespace='notifications')),
|
|
123
|
+
...
|
|
124
|
+
]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
To run schema migration, execute
|
|
128
|
+
`python manage.py migrate notifications`.
|
|
129
|
+
|
|
130
|
+
## Generating Notifications
|
|
131
|
+
|
|
132
|
+
Generating notifications is probably best done in a separate signal.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from django.db.models.signals import post_save
|
|
136
|
+
from notifications.signals import notify
|
|
137
|
+
from myapp.models import MyModel
|
|
138
|
+
|
|
139
|
+
def my_handler(sender, instance, created, **kwargs):
|
|
140
|
+
notify.send(instance, verb='was saved')
|
|
141
|
+
|
|
142
|
+
post_save.connect(my_handler, sender=MyModel)
|
|
143
|
+
```
|
|
144
|
+
To generate an notification anywhere in your code, simply import the
|
|
145
|
+
notify signal and send it with your actor, recipient, and verb.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from notifications.signals import notify
|
|
149
|
+
|
|
150
|
+
notify.send(user, recipient=user, verb='you reached level 10')
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The complete syntax is.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
notify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Arguments:
|
|
160
|
+
|
|
161
|
+
- **actor**: An object of any type. (Required) Note: Use
|
|
162
|
+
**sender** instead of **actor** if you intend to use keyword
|
|
163
|
+
arguments
|
|
164
|
+
- **recipient**: A **Group** or a **User QuerySet** or a list of
|
|
165
|
+
**User**. (Required)
|
|
166
|
+
- **verb**: An string. (Required)
|
|
167
|
+
- **action\_object**: An object of any type. (Optional)
|
|
168
|
+
- **target**: An object of any type. (Optional)
|
|
169
|
+
- **level**: One of Notification.LEVELS (\'success\', \'info\',
|
|
170
|
+
\'warning\', \'error\') (default=info). (Optional)
|
|
171
|
+
- **description**: An string. (Optional)
|
|
172
|
+
- **public**: An boolean (default=True). (Optional)
|
|
173
|
+
- **timestamp**: An tzinfo (default=timezone.now()). (Optional)
|
|
174
|
+
|
|
175
|
+
### Extra data
|
|
176
|
+
|
|
177
|
+
You can attach arbitrary data to your notifications by doing the
|
|
178
|
+
following:
|
|
179
|
+
|
|
180
|
+
- Add to your settings.py:
|
|
181
|
+
`DJANGO_NOTIFICATIONS_CONFIG = { 'USE_JSONFIELD': True}`
|
|
182
|
+
|
|
183
|
+
Then, any extra arguments you pass to `notify.send(...)` will be
|
|
184
|
+
attached to the `.data` attribute of the notification object. These will
|
|
185
|
+
be serialised using the JSONField\'s serialiser, so you may need to take
|
|
186
|
+
that into account: using only objects that will be serialised is a good
|
|
187
|
+
idea.
|
|
188
|
+
|
|
189
|
+
### Soft delete
|
|
190
|
+
|
|
191
|
+
By default, `delete/(?P<slug>\d+)/` deletes specified notification
|
|
192
|
+
record from DB. You can change this behaviour to \"mark
|
|
193
|
+
`Notification.deleted` field as `True`\" by:
|
|
194
|
+
|
|
195
|
+
- Add to your settings.py:
|
|
196
|
+
`DJANGO_NOTIFICATIONS_CONFIG = { 'SOFT_DELETE': True}`
|
|
197
|
+
|
|
198
|
+
With this option, QuerySet methods `unread` and `read` contain one more
|
|
199
|
+
filter: `deleted=False`. Meanwhile, QuerySet methods `deleted`,
|
|
200
|
+
`active`, `mark_all_as_deleted`, `mark_all_as_active` are turned on. See
|
|
201
|
+
more details in QuerySet methods section.
|
|
202
|
+
|
|
203
|
+
## API
|
|
204
|
+
|
|
205
|
+
### QuerySet methods
|
|
206
|
+
|
|
207
|
+
Using `django-model-utils`, we get the ability to add queryset methods
|
|
208
|
+
to not only the manager, but to all querysets that will be used,
|
|
209
|
+
including related objects. This enables us to do things like:
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
Notification.objects.unread()
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
which returns all unread notifications. To do this for a single user, we
|
|
216
|
+
can do:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
user = User.objects.get(pk=pk)
|
|
220
|
+
user.notifications.unread()
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
There are some other QuerySet methods, too.
|
|
224
|
+
|
|
225
|
+
#### `qs.unsent()`
|
|
226
|
+
|
|
227
|
+
Return all of the unsent notifications, filtering the current queryset.
|
|
228
|
+
(emailed=False)
|
|
229
|
+
|
|
230
|
+
#### `qs.sent()`
|
|
231
|
+
|
|
232
|
+
Return all of the sent notifications, filtering the current queryset.
|
|
233
|
+
(emailed=True)
|
|
234
|
+
|
|
235
|
+
#### `qs.unread()`
|
|
236
|
+
|
|
237
|
+
Return all of the unread notifications, filtering the current queryset.
|
|
238
|
+
When `SOFT_DELETE=True`, this filter contains `deleted=False`.
|
|
239
|
+
|
|
240
|
+
#### `qs.read()`
|
|
241
|
+
|
|
242
|
+
Return all of the read notifications, filtering the current queryset.
|
|
243
|
+
When `SOFT_DELETE=True`, this filter contains `deleted=False`.
|
|
244
|
+
|
|
245
|
+
#### `qs.mark_all_as_read()` \| `qs.mark_all_as_read(recipient)`
|
|
246
|
+
|
|
247
|
+
Mark all of the unread notifications in the queryset (optionally also
|
|
248
|
+
filtered by `recipient`) as read.
|
|
249
|
+
|
|
250
|
+
#### `qs.mark_all_as_unread()` \| `qs.mark_all_as_unread(recipient)`
|
|
251
|
+
|
|
252
|
+
Mark all of the read notifications in the queryset (optionally also
|
|
253
|
+
filtered by `recipient`) as unread.
|
|
254
|
+
|
|
255
|
+
#### `qs.mark_as_sent()` \| `qs.mark_as_sent(recipient)`
|
|
256
|
+
|
|
257
|
+
Mark all of the unsent notifications in the queryset (optionally also
|
|
258
|
+
filtered by `recipient`) as sent.
|
|
259
|
+
|
|
260
|
+
#### `qs.mark_as_unsent()` \| `qs.mark_as_unsent(recipient)`
|
|
261
|
+
|
|
262
|
+
Mark all of the sent notifications in the queryset (optionally also
|
|
263
|
+
filtered by `recipient`) as unsent.
|
|
264
|
+
|
|
265
|
+
#### `qs.deleted()`
|
|
266
|
+
|
|
267
|
+
Return all notifications that have `deleted=True`, filtering the current
|
|
268
|
+
queryset. Must be used with `SOFT_DELETE=True`.
|
|
269
|
+
|
|
270
|
+
#### `qs.active()`
|
|
271
|
+
|
|
272
|
+
Return all notifications that have `deleted=False`, filtering the
|
|
273
|
+
current queryset. Must be used with `DELETE=True`.
|
|
274
|
+
|
|
275
|
+
#### `qs.mark_all_as_deleted()` \| `qs.mark_all_as_deleted(recipient)`
|
|
276
|
+
|
|
277
|
+
Mark all notifications in the queryset (optionally also filtered by
|
|
278
|
+
`recipient`) as `deleted=True`. Must be used with `DELETE=True`.
|
|
279
|
+
|
|
280
|
+
#### `qs.mark_all_as_active()` \| `qs.mark_all_as_active(recipient)`
|
|
281
|
+
|
|
282
|
+
Mark all notifications in the queryset (optionally also filtered by
|
|
283
|
+
`recipient`) as `deleted=False`. Must be used with `SOFT_DELETE=True`.
|
|
284
|
+
|
|
285
|
+
### Model methods
|
|
286
|
+
|
|
287
|
+
#### `obj.timesince([datetime])`
|
|
288
|
+
|
|
289
|
+
A wrapper for Django\'s `timesince` function.
|
|
290
|
+
|
|
291
|
+
#### `obj.mark_as_read()`
|
|
292
|
+
|
|
293
|
+
Mark the current object as read.
|
|
294
|
+
|
|
295
|
+
### Template tags
|
|
296
|
+
|
|
297
|
+
Put `{% load notifications_tags %}` in the template before
|
|
298
|
+
you actually use notification tags.
|
|
299
|
+
|
|
300
|
+
### `notifications_unread`
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
{% notifications_unread %}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Give the number of unread notifications for a user, or nothing (an empty
|
|
307
|
+
string) for an anonymous user.
|
|
308
|
+
|
|
309
|
+
Storing the count in a variable for further processing is advised, such
|
|
310
|
+
as:
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
{% notifications_unread as unread_count %}
|
|
314
|
+
...
|
|
315
|
+
{% if unread_count %}
|
|
316
|
+
You have <strong>{{ unread_count }}</strong> unread notifications.
|
|
317
|
+
{% endif %}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Live-updater API
|
|
321
|
+
|
|
322
|
+
To ensure users always have the most up-to-date notifications,
|
|
323
|
+
`django-notifications` includes a simple javascript API for
|
|
324
|
+
updating specific fields within a django template.
|
|
325
|
+
|
|
326
|
+
There are two possible API calls that can be made:
|
|
327
|
+
|
|
328
|
+
1. `api/unread_count/` that returns a javascript object with 1 key:
|
|
329
|
+
`unread_count` eg:
|
|
330
|
+
|
|
331
|
+
{"unread_count":1}
|
|
332
|
+
|
|
333
|
+
2. `api/unread_list/` that returns a javascript object with 2 keys:
|
|
334
|
+
`unread_count` and `unread_list` eg:
|
|
335
|
+
|
|
336
|
+
{
|
|
337
|
+
"unread_count":1,
|
|
338
|
+
"unread_list":[--list of json representations of notifications--]
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
Representations of notifications are based on the django method:
|
|
342
|
+
`model_to_dict`
|
|
343
|
+
|
|
344
|
+
Query string arguments:
|
|
345
|
+
|
|
346
|
+
- **max** - maximum length of unread list.
|
|
347
|
+
- **mark\_as\_read** - mark notification in list as read.
|
|
348
|
+
|
|
349
|
+
For example, get `api/unread_list/?max=3&mark_as_read=true` returns
|
|
350
|
+
3 notifications and mark them read (remove from list on next
|
|
351
|
+
request).
|
|
352
|
+
|
|
353
|
+
The list outputs `target_url`, `actor_url`, `action_object_url`.
|
|
354
|
+
This URL is generated from standard Django `Model.get_absolute_url()` or
|
|
355
|
+
you can override the URL just for notifications by implementing
|
|
356
|
+
`Model.get_url_for_notifications(notification, request)`.
|
|
357
|
+
|
|
358
|
+
### How to use:
|
|
359
|
+
|
|
360
|
+
1. Put `{% load notifications_tags %}` in the template before you
|
|
361
|
+
actually use notification tags.
|
|
362
|
+
|
|
363
|
+
2. In the area where you are loading javascript resources add the
|
|
364
|
+
following tags in the order below:
|
|
365
|
+
|
|
366
|
+
<script src="{% static 'notifications/notify.js' %}" type="text/javascript"></script>
|
|
367
|
+
{% register_notify_callbacks callbacks='fill_notification_list,fill_notification_badge' %}
|
|
368
|
+
|
|
369
|
+
`register_notify_callbacks` takes the following arguments:
|
|
370
|
+
|
|
371
|
+
1. `badge_class` (default `live_notify_badge`) - The identifier
|
|
372
|
+
`class` of the element to show the unread count,
|
|
373
|
+
that will be periodically updated.
|
|
374
|
+
2. `menu_class` (default `live_notify_list`) - The identifier
|
|
375
|
+
`class` of the element to insert a list of unread
|
|
376
|
+
items, that will be periodically updated.
|
|
377
|
+
3. `refresh_period` (default `15`) - How often to fetch unread
|
|
378
|
+
items from the server (integer in seconds).
|
|
379
|
+
4. `fetch` (default `5`) - How many notifications to fetch each
|
|
380
|
+
time.
|
|
381
|
+
5. `callbacks` (default `<empty string>`) - A comma-separated list
|
|
382
|
+
of javascript functions to call each period.
|
|
383
|
+
6. `api_name` (default `list`) - The name of the API to call (this
|
|
384
|
+
can be either `list` or `count`).
|
|
385
|
+
7. ``mark_as_read`` (default ``False``) - Marks notifications as read when fetched.
|
|
386
|
+
|
|
387
|
+
3. To insert a live-updating unread count, use the following template:
|
|
388
|
+
|
|
389
|
+
{% live_notify_badge %}
|
|
390
|
+
|
|
391
|
+
`live_notify_badge` takes the following arguments:
|
|
392
|
+
|
|
393
|
+
- `badge_class` (default `live_notify_badge`) - The identifier
|
|
394
|
+
`class` for the `<span>` element that will be created to show
|
|
395
|
+
the unread count.
|
|
396
|
+
|
|
397
|
+
4. To insert a live-updating unread list, use the following template:
|
|
398
|
+
|
|
399
|
+
{% live_notify_list %}
|
|
400
|
+
|
|
401
|
+
`live_notify_list` takes the following arguments:
|
|
402
|
+
|
|
403
|
+
- `list_class` (default `live_notify_list`) - The identifier
|
|
404
|
+
`class` for the `<ul>` element that will be created to insert
|
|
405
|
+
the list of notifications into.
|
|
406
|
+
|
|
407
|
+
### Using the live-updater with bootstrap
|
|
408
|
+
|
|
409
|
+
The Live-updater can be incorporated into bootstrap with minimal code.
|
|
410
|
+
|
|
411
|
+
To create a live-updating bootstrap badge containing the unread count,
|
|
412
|
+
simply use the template tag:
|
|
413
|
+
|
|
414
|
+
{% live_notify_badge badge_class="badge" %}
|
|
415
|
+
|
|
416
|
+
To create a live-updating bootstrap dropdown menu containing a selection
|
|
417
|
+
of recent unread notifications, simply use the template tag:
|
|
418
|
+
|
|
419
|
+
{% live_notify_list list_class="dropdown-menu" %}
|
|
420
|
+
|
|
421
|
+
### Customising the display of notifications using javascript callbacks
|
|
422
|
+
|
|
423
|
+
While the live notifier for unread counts should suit most use cases,
|
|
424
|
+
users may wish to alter how unread notifications are shown.
|
|
425
|
+
|
|
426
|
+
The `callbacks` argument of the `register_notify_callbacks` dictates
|
|
427
|
+
which javascript functions are called when the unread api call is made.
|
|
428
|
+
|
|
429
|
+
To add a custom javascript callback, simply add this to the list, like
|
|
430
|
+
so:
|
|
431
|
+
|
|
432
|
+
{% register_notify_callbacks callbacks='fill_notification_badge,my_special_notification_callback' %}
|
|
433
|
+
|
|
434
|
+
The above would cause the callback to update the unread count badge, and
|
|
435
|
+
would call the custom function
|
|
436
|
+
`my_special_notification_callback`. All callback
|
|
437
|
+
functions are passed a single argument by convention called
|
|
438
|
+
`data`, which contains the entire result from the API.
|
|
439
|
+
|
|
440
|
+
For example, the below function would get the recent list of unread
|
|
441
|
+
messages and log them to the console:
|
|
442
|
+
|
|
443
|
+
```javascript
|
|
444
|
+
function my_special_notification_callback(data) {
|
|
445
|
+
for (var i=0; i < data.unread_list.length; i++) {
|
|
446
|
+
msg = data.unread_list[i];
|
|
447
|
+
console.log(msg);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Testing the live-updater
|
|
453
|
+
|
|
454
|
+
1. Clone the repo
|
|
455
|
+
2. Run `./manage.py runserver`
|
|
456
|
+
3. Browse to `yourserverip/test/`
|
|
457
|
+
4. Click \'Make a notification\' and a new notification should appear
|
|
458
|
+
in the list in 5-10 seconds.
|
|
459
|
+
|
|
460
|
+
## Serializing the django-notifications Model
|
|
461
|
+
|
|
462
|
+
See here - <http://www.django-rest-framework.org/api-guide/relations/#generic-relationships>
|
|
463
|
+
|
|
464
|
+
In this example the target object can be of type Foo or Bar and the
|
|
465
|
+
appropriate serializer will be used.
|
|
466
|
+
|
|
467
|
+
```python
|
|
468
|
+
class GenericNotificationRelatedField(serializers.RelatedField):
|
|
469
|
+
|
|
470
|
+
def to_representation(self, value):
|
|
471
|
+
if isinstance(value, Foo):
|
|
472
|
+
serializer = FooSerializer(value)
|
|
473
|
+
if isinstance(value, Bar):
|
|
474
|
+
serializer = BarSerializer(value)
|
|
475
|
+
|
|
476
|
+
return serializer.data
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
class NotificationSerializer(serializers.Serializer):
|
|
480
|
+
recipient = PublicUserSerializer(User, read_only=True)
|
|
481
|
+
unread = serializers.BooleanField(read_only=True)
|
|
482
|
+
target = GenericNotificationRelatedField(read_only=True)
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Thanks to @DaWy
|
|
486
|
+
|
|
487
|
+
### `AbstractNotification` model
|
|
488
|
+
|
|
489
|
+
In case you need to customize the notification model in order to add
|
|
490
|
+
field or customised features that depend on your application, you can
|
|
491
|
+
inherit and extend the `AbstractNotification` model, example:
|
|
492
|
+
|
|
493
|
+
```python
|
|
494
|
+
#In your_app/models.py
|
|
495
|
+
|
|
496
|
+
from django.db import models
|
|
497
|
+
from notifications.base.models import AbstractNotification
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class Notification(AbstractNotification):
|
|
501
|
+
# custom field example
|
|
502
|
+
category = models.ForeignKey('myapp.Category',
|
|
503
|
+
on_delete=models.CASCADE)
|
|
504
|
+
|
|
505
|
+
class Meta(AbstractNotification.Meta):
|
|
506
|
+
abstract = False
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
You will require to define `NOTIFICATIONS_NOTIFICATION_MODEL` setting in
|
|
510
|
+
`setting.py` as follows:
|
|
511
|
+
|
|
512
|
+
```python
|
|
513
|
+
# In your_project/settings.py
|
|
514
|
+
|
|
515
|
+
NOTIFICATIONS_NOTIFICATION_MODEL = 'your_app.Notification'
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## Notes
|
|
519
|
+
|
|
520
|
+
### Email Notification
|
|
521
|
+
|
|
522
|
+
Sending email to users has not been integrated into this library. So for
|
|
523
|
+
now you need to implement it if needed. There is a reserved field
|
|
524
|
+
`Notification.emailed` to make it easier.
|
|
525
|
+
|
|
526
|
+
### Sample App
|
|
527
|
+
|
|
528
|
+
A sample app has been implemented in
|
|
529
|
+
`notifications/tests/sample_notifications` that extends
|
|
530
|
+
`django-notifications` with the sole purpose of testing its
|
|
531
|
+
extensibility. You can run the SAMPLE APP by setting the environment
|
|
532
|
+
variable `SAMPLE_APP` as follows
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
export SAMPLE_APP=1
|
|
536
|
+
# Run the Django development server with sample_notifications app installed
|
|
537
|
+
python manage.py runserver
|
|
538
|
+
# Unset SAMPLE_APP to remove sample_notifications app from list of INSTALLED_APPS
|
|
539
|
+
unset SAMPLE_APP
|
|
540
|
+
```
|