# Fork of `django-notifications` with some additional features
## Requirements
- Django >= 3.8 *
- Python >= 3.8 *
- djangorestframework >= 3.13
- django-model-utils >= 3.1.0
- jsonfield >= 2.1.0
- pandas >= 2.2.0
- requests >= 2.30
Add `django_notifications_pro` app to INSTALLED_APPS in your django settings.py:
```python
INSTALLED_APPS = (
...,
"django.contrib.staticfiles",
"rest_framework", # required only if using the provided REST endpoints
'notifications',
'django_notifications_pro',
...,
)
```
## General ViewSets endpoints added (with custom serializer):
- GET /api/notifications/ : Get all notifications for the current user
- POST /api/notifications/read-all/ : Mark all notifications as read for the current user
- GET /api/notifications/<int:pk>/ : Get a notification by id and mark it as read
## Cron for deleting old notifications
You can set up a cron job to delete old notifications automatically.
This install is needed to enable cron job.
```bash
pip install django-notifications-pro[cron]
service cron start
python manage.py crontab add
```
Add the following to your settings.py :
```python
DJANGO_NOTIFICATIONS_CONFIG = {
'AUTO_DELETE_NOTIFICATIONS': True,
'NOTIFICATIONS_DELETE_DAYS': 30, # Number of days to keep notifications (default is 30)
}
CRONJOBS = [
('0 0 * * *', 'notifications.cron.delete_old_notifications'), # Delete old notifications every day at midnight
]
```
## Expo notifications
You will be able to register devices, and each time a notification is sent, it will be delivered through Expo Go Notifications.
This install is needed to enable expo notifications.
```bash
pip install django-notifications-pro[expo]
```
Add the following to your settings.py :
```python
DJANGO_NOTIFICATIONS_VIEWS = {
'USE_EXPO_NOTIFICATIONS': True, # Set to True to enable expo notifications
'EXPO_APP_ID': '<your-expo-app-id>',
}
```
Then run the migrations:
```bash
python manage.py makemigrations
python manage.py migrate
```
## Urls
### Expo Notifications
- POST /api/expo-devices/register-device/ : Register a device to receive expo notifications
- POST /api/expo-devices/unregister-device/ : Unregister a device to stop receiving expo notifications
## Contributing
- [Juan Ignacio Borrelli](https://www.linkedin.com/in/juan-ignacio-borrelli/)
Maintained and developed by [Linkchar Software Development](https://linkchar.com/).
# Original `django-notifications` Documentation
[![build-status](https://travis-ci.org/django-notifications/django-notifications.svg)](https://travis-ci.org/django-notifications/django-notifications)
[![Coverage Status](https://coveralls.io/repos/github/django-notifications/django-notifications/badge.svg?branch=master)](https://coveralls.io/github/django-notifications/django-notifications?branch=master)
[django-notifications](https://github.com/django-notifications/django-notifications) is a GitHub notification alike app for Django, it was derived from [django-activity-stream](https://github.com/justquick/django-activity-stream)
The major difference between `django-notifications` and `django-activity-stream`:
- `django-notifications` is for building something like Github "Notifications"
- While `django-activity-stream` is for building Github "News Feed"
Notifications are actually actions events, which are categorized by four main components.
- `Actor`. The object that performed the activity.
- `Verb`. The verb phrase that identifies the action of the activity.
- `Action Object`. *(Optional)* The object linked to the action
itself.
- `Target`. *(Optional)* The object to which the activity was
performed.
`Actor`, `Action Object` and `Target` are `GenericForeignKeys` to any
arbitrary Django object. An action is a description of an action that
was performed (`Verb`) at some instant in time by some `Actor` on some
optional `Target` that results in an `Action Object` getting
created/updated/deleted.
For example: [justquick](https://github.com/justquick/) `(actor)`
*closed* `(verb)` [issue
2](https://github.com/justquick/django-activity-stream/issues/2)
`(action_object)` on
[activity-stream](https://github.com/justquick/django-activity-stream/)
`(target)` 12 hours ago
Nomenclature of this specification is based on the Activity Streams
Spec: <http://activitystrea.ms/specs/atom/1.0/>
## Requirements
- Python 3.7, 3.8, 3.9, 3.10, 3.11
- Django 3.2, 4.0, 4.1
## Installation
Installation is easy using `pip` and will install all required
libraries.
```bash
$ pip install django-notifications-hq
```
or get it from source
```bash
$ git clone https://github.com/django-notifications/django-notifications
$ cd django-notifications
$ python setup.py sdist
$ pip install dist/django-notifications-hq*
```
Note that [django-model-utils](http://pypi.python.org/pypi/django-model-utils)
will be installed: this is required for the pass-through QuerySet manager.
Then to add the Django Notifications to your project add the app
`notifications` to your `INSTALLED_APPS` and urlconf.
The app should go somewhere after all the apps that are going to be
generating notifications like `django.contrib.auth`
```python
INSTALLED_APPS = (
'django.contrib.auth',
...
'notifications',
...
)
```
Add the notifications urls to your urlconf:
```python
urlpatterns = [
...
path('inbox/notifications/', include('notifications.urls', namespace='notifications')),
...
]
```
To run schema migration, execute
`python manage.py migrate notifications`.
## Generating Notifications
Generating notifications is probably best done in a separate signal.
```python
from django.db.models.signals import post_save
from notifications.signals import notify
from myapp.models import MyModel
def my_handler(sender, instance, created, **kwargs):
notify.send(instance, verb='was saved')
post_save.connect(my_handler, sender=MyModel)
```
To generate an notification anywhere in your code, simply import the
notify signal and send it with your actor, recipient, and verb.
```python
from notifications.signals import notify
notify.send(user, recipient=user, verb='you reached level 10')
```
The complete syntax is.
```python
notify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)
```
Arguments:
- **actor**: An object of any type. (Required) Note: Use
**sender** instead of **actor** if you intend to use keyword
arguments
- **recipient**: A **Group** or a **User QuerySet** or a list of
**User**. (Required)
- **verb**: An string. (Required)
- **action\_object**: An object of any type. (Optional)
- **target**: An object of any type. (Optional)
- **level**: One of Notification.LEVELS (\'success\', \'info\',
\'warning\', \'error\') (default=info). (Optional)
- **description**: An string. (Optional)
- **public**: An boolean (default=True). (Optional)
- **timestamp**: An tzinfo (default=timezone.now()). (Optional)
### Extra data
You can attach arbitrary data to your notifications by doing the
following:
- Add to your settings.py:
`DJANGO_NOTIFICATIONS_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.
### 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:
`DJANGO_NOTIFICATIONS_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. See
more details in QuerySet methods section.
## API
### QuerySet methods
Using `django-model-utils`, we get the ability to add queryset methods
to not only the manager, but to all querysets that will be used,
including related objects. This enables us to do things like:
```python
Notification.objects.unread()
```
which returns all unread notifications. To do this for a single user, we
can do:
```python
user = User.objects.get(pk=pk)
user.notifications.unread()
```
There are some other QuerySet methods, too.
#### `qs.unsent()`
Return all of the unsent notifications, filtering the current queryset.
(emailed=False)
#### `qs.sent()`
Return all of the sent notifications, filtering the current queryset.
(emailed=True)
#### `qs.unread()`
Return all of the unread notifications, filtering the current queryset.
When `SOFT_DELETE=True`, this filter contains `deleted=False`.
#### `qs.read()`
Return all of the read notifications, filtering the current queryset.
When `SOFT_DELETE=True`, this filter contains `deleted=False`.
#### `qs.mark_all_as_read()` \| `qs.mark_all_as_read(recipient)`
Mark all of the unread notifications in the queryset (optionally also
filtered by `recipient`) as read.
#### `qs.mark_all_as_unread()` \| `qs.mark_all_as_unread(recipient)`
Mark all of the read notifications in the queryset (optionally also
filtered by `recipient`) as unread.
#### `qs.mark_as_sent()` \| `qs.mark_as_sent(recipient)`
Mark all of the unsent notifications in the queryset (optionally also
filtered by `recipient`) as sent.
#### `qs.mark_as_unsent()` \| `qs.mark_as_unsent(recipient)`
Mark all of the sent notifications in the queryset (optionally also
filtered by `recipient`) as unsent.
#### `qs.deleted()`
Return all notifications that have `deleted=True`, filtering the current
queryset. Must be used with `SOFT_DELETE=True`.
#### `qs.active()`
Return all notifications that have `deleted=False`, filtering the
current queryset. 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 `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 `SOFT_DELETE=True`.
### Model methods
#### `obj.timesince([datetime])`
A wrapper for Django\'s `timesince` function.
#### `obj.mark_as_read()`
Mark the current object as read.
### Template tags
Put `{% load notifications_tags %}` in the template before
you actually use notification tags.
### `notifications_unread`
```python
{% notifications_unread %}
```
Give the number of unread notifications for a user, or nothing (an empty
string) for an anonymous user.
Storing the count in a variable for further processing is advised, such
as:
```python
{% notifications_unread as unread_count %}
...
{% if unread_count %}
You have <strong>{{ unread_count }}</strong> unread notifications.
{% endif %}
```
## Live-updater API
To ensure users always have the most up-to-date notifications,
`django-notifications` includes a simple javascript API for
updating specific fields within a django template.
There are two possible API calls that can be made:
1. `api/unread_count/` that returns a javascript object with 1 key:
`unread_count` eg:
{"unread_count":1}
2. `api/unread_list/` that returns a javascript object with 2 keys:
`unread_count` and `unread_list` eg:
{
"unread_count":1,
"unread_list":[--list of json representations of notifications--]
}
Representations of notifications are based on the django method:
`model_to_dict`
Query string arguments:
- **max** - maximum length of unread list.
- **mark\_as\_read** - mark notification in list as read.
For example, get `api/unread_list/?max=3&mark_as_read=true` returns
3 notifications and mark them read (remove from list on next
request).
The list outputs `target_url`, `actor_url`, `action_object_url`.
This URL is generated from standard Django `Model.get_absolute_url()` or
you can override the URL just for notifications by implementing
`Model.get_url_for_notifications(notification, request)`.
### How to use:
1. Put `{% load notifications_tags %}` in the template before you
actually use notification tags.
2. In the area where you are loading javascript resources add the
following tags in the order below:
<script src="{% static 'notifications/notify.js' %}" type="text/javascript"></script>
{% register_notify_callbacks callbacks='fill_notification_list,fill_notification_badge' %}
`register_notify_callbacks` takes the following arguments:
1. `badge_class` (default `live_notify_badge`) - The identifier
`class` of the element to show the unread count,
that will be periodically updated.
2. `menu_class` (default `live_notify_list`) - The identifier
`class` of the element to insert a list of unread
items, that will be periodically updated.
3. `refresh_period` (default `15`) - How often to fetch unread
items from the server (integer in seconds).
4. `fetch` (default `5`) - How many notifications to fetch each
time.
5. `callbacks` (default `<empty string>`) - A comma-separated list
of javascript functions to call each period.
6. `api_name` (default `list`) - The name of the API to call (this
can be either `list` or `count`).
7. ``mark_as_read`` (default ``False``) - Marks notifications as read when fetched.
3. To insert a live-updating unread count, use the following template:
{% live_notify_badge %}
`live_notify_badge` takes the following arguments:
- `badge_class` (default `live_notify_badge`) - The identifier
`class` for the `<span>` element that will be created to show
the unread count.
4. To insert a live-updating unread list, use the following template:
{% live_notify_list %}
`live_notify_list` takes the following arguments:
- `list_class` (default `live_notify_list`) - The identifier
`class` for the `<ul>` element that will be created to insert
the list of notifications into.
### Using the live-updater with bootstrap
The Live-updater can be incorporated into bootstrap with minimal code.
To create a live-updating bootstrap badge containing the unread count,
simply use the template tag:
{% live_notify_badge badge_class="badge" %}
To create a live-updating bootstrap dropdown menu containing a selection
of recent unread notifications, simply use the template tag:
{% live_notify_list list_class="dropdown-menu" %}
### Customising the display of notifications using javascript callbacks
While the live notifier for unread counts should suit most use cases,
users may wish to alter how unread notifications are shown.
The `callbacks` argument of the `register_notify_callbacks` dictates
which javascript functions are called when the unread api call is made.
To add a custom javascript callback, simply add this to the list, like
so:
{% register_notify_callbacks callbacks='fill_notification_badge,my_special_notification_callback' %}
The above would cause the callback to update the unread count badge, and
would call the custom function
`my_special_notification_callback`. All callback
functions are passed a single argument by convention called
`data`, which contains the entire result from the API.
For example, the below function would get the recent list of unread
messages and log them to the console:
```javascript
function my_special_notification_callback(data) {
for (var i=0; i < data.unread_list.length; i++) {
msg = data.unread_list[i];
console.log(msg);
}
}
```
### Testing the live-updater
1. Clone the repo
2. Run `./manage.py runserver`
3. Browse to `yourserverip/test/`
4. Click \'Make a notification\' and a new notification should appear
in the list in 5-10 seconds.
## Serializing the django-notifications Model
See here - <http://www.django-rest-framework.org/api-guide/relations/#generic-relationships>
In this example the target object can be of type Foo or Bar and the
appropriate serializer will be used.
```python
class GenericNotificationRelatedField(serializers.RelatedField):
def to_representation(self, value):
if isinstance(value, Foo):
serializer = FooSerializer(value)
if isinstance(value, Bar):
serializer = BarSerializer(value)
return serializer.data
class NotificationSerializer(serializers.Serializer):
recipient = PublicUserSerializer(User, read_only=True)
unread = serializers.BooleanField(read_only=True)
target = GenericNotificationRelatedField(read_only=True)
```
Thanks to @DaWy
### `AbstractNotification` model
In case you need to customize the notification model in order to add
field or customised features that depend on your application, you can
inherit and extend the `AbstractNotification` model, example:
```python
#In your_app/models.py
from django.db import models
from notifications.base.models import AbstractNotification
class Notification(AbstractNotification):
# custom field example
category = models.ForeignKey('myapp.Category',
on_delete=models.CASCADE)
class Meta(AbstractNotification.Meta):
abstract = False
```
You will require to define `NOTIFICATIONS_NOTIFICATION_MODEL` setting in
`setting.py` as follows:
```python
# In your_project/settings.py
NOTIFICATIONS_NOTIFICATION_MODEL = 'your_app.Notification'
```
## Notes
### Email Notification
Sending email to users has not been integrated into this library. So for
now you need to implement it if needed. There is a reserved field
`Notification.emailed` to make it easier.
### Sample App
A sample app has been implemented in
`notifications/tests/sample_notifications` that extends
`django-notifications` with the sole purpose of testing its
extensibility. You can run the SAMPLE APP by setting the environment
variable `SAMPLE_APP` as follows
```bash
export SAMPLE_APP=1
# Run the Django development server with sample_notifications app installed
python manage.py runserver
# Unset SAMPLE_APP to remove sample_notifications app from list of INSTALLED_APPS
unset SAMPLE_APP
```
## `django-notifications` Team
Core contributors (in alphabetical order):
- [Alvaro Leonel](https://github.com/AlvaroLQueiroz)
- [Federico Capoano](https://github.com/nemesisdesign)
- [Samuel Spencer](https://github.com/LegoStormtroopr)
- [Yang Yubo](https://github.com/yangyubo)
- [YPCrumble](https://github.com/YPCrumble)
- [Zhongyuan Zhang](https://github.com/zhang-z)
## Contribute
We are looking for contributors, for anyone who\'d like to contribute
and willing to put time and energy on this project, please contact [Yang
Yubo](https://github.com/yangyubo).
Raw data
{
"_id": null,
"home_page": "https://github.com/nachoborrelli/django-notifications",
"name": "django-notifications-pro",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "django notifications github action event stream expo push viewset cron crontab",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/42/68/ec85c2be78f65cd0b0646acc2f81c6f5f1b12e068638a7ffe054d2ba72ef/django_notifications_pro-1.8.0.tar.gz",
"platform": null,
"description": "# Fork of `django-notifications` with some additional features\n\n## Requirements\n- Django >= 3.8 *\n- Python >= 3.8 *\n- djangorestframework >= 3.13\n- django-model-utils >= 3.1.0\n- jsonfield >= 2.1.0\n- pandas >= 2.2.0\n- requests >= 2.30\n\n\nAdd `django_notifications_pro` app to INSTALLED_APPS in your django settings.py:\n```python\nINSTALLED_APPS = (\n ...,\n \"django.contrib.staticfiles\",\n \"rest_framework\", # required only if using the provided REST endpoints\n 'notifications',\n 'django_notifications_pro',\n ...,\n)\n```\n\n\n## General ViewSets endpoints added (with custom serializer):\n- GET /api/notifications/ : Get all notifications for the current user\n- POST /api/notifications/read-all/ : Mark all notifications as read for the current user\n- GET /api/notifications/<int:pk>/ : Get a notification by id and mark it as read\n\n\n## Cron for deleting old notifications\nYou can set up a cron job to delete old notifications automatically.\n\nThis install is needed to enable cron job.\n```bash\npip install django-notifications-pro[cron]\nservice cron start\npython manage.py crontab add\n\n```\n\nAdd the following to your settings.py :\n\n```python\nDJANGO_NOTIFICATIONS_CONFIG = {\n 'AUTO_DELETE_NOTIFICATIONS': True,\n 'NOTIFICATIONS_DELETE_DAYS': 30, # Number of days to keep notifications (default is 30)\n}\n\nCRONJOBS = [\n ('0 0 * * *', 'notifications.cron.delete_old_notifications'), # Delete old notifications every day at midnight\n]\n```\n\n\n\n## Expo notifications\nYou will be able to register devices, and each time a notification is sent, it will be delivered through Expo Go Notifications.\n\n\nThis install is needed to enable expo notifications.\n```bash\npip install django-notifications-pro[expo]\n```\n\nAdd the following to your settings.py :\n\n```python\nDJANGO_NOTIFICATIONS_VIEWS = {\n 'USE_EXPO_NOTIFICATIONS': True, # Set to True to enable expo notifications\n 'EXPO_APP_ID': '<your-expo-app-id>', \n}\n```\n\nThen run the migrations:\n```bash\npython manage.py makemigrations\npython manage.py migrate\n```\n\n## Urls\n ### Expo Notifications\n- POST /api/expo-devices/register-device/ : Register a device to receive expo notifications\n- POST /api/expo-devices/unregister-device/ : Unregister a device to stop receiving expo notifications\n\n\n## Contributing\n\n- [Juan Ignacio Borrelli](https://www.linkedin.com/in/juan-ignacio-borrelli/)\n \n\nMaintained and developed by [Linkchar Software Development](https://linkchar.com/).\n\n\n\n\n# Original `django-notifications` Documentation\n\n[![build-status](https://travis-ci.org/django-notifications/django-notifications.svg)](https://travis-ci.org/django-notifications/django-notifications)\n[![Coverage Status](https://coveralls.io/repos/github/django-notifications/django-notifications/badge.svg?branch=master)](https://coveralls.io/github/django-notifications/django-notifications?branch=master)\n\n\n[django-notifications](https://github.com/django-notifications/django-notifications) is a GitHub notification alike app for Django, it was derived from [django-activity-stream](https://github.com/justquick/django-activity-stream)\n\nThe major difference between `django-notifications` and `django-activity-stream`:\n\n- `django-notifications` is for building something like Github \"Notifications\"\n- While `django-activity-stream` is for building Github \"News Feed\"\n\nNotifications are actually actions events, which are categorized by four main components.\n\n- `Actor`. The object that performed the activity.\n- `Verb`. The verb phrase that identifies the action of the activity.\n- `Action Object`. *(Optional)* The object linked to the action\n itself.\n- `Target`. *(Optional)* The object to which the activity was\n performed.\n\n`Actor`, `Action Object` and `Target` are `GenericForeignKeys` to any\narbitrary Django object. An action is a description of an action that\nwas performed (`Verb`) at some instant in time by some `Actor` on some\noptional `Target` that results in an `Action Object` getting\ncreated/updated/deleted.\n\nFor example: [justquick](https://github.com/justquick/) `(actor)`\n*closed* `(verb)` [issue\n2](https://github.com/justquick/django-activity-stream/issues/2)\n`(action_object)` on\n[activity-stream](https://github.com/justquick/django-activity-stream/)\n`(target)` 12 hours ago\n\nNomenclature of this specification is based on the Activity Streams\nSpec: <http://activitystrea.ms/specs/atom/1.0/>\n\n## Requirements\n\n- Python 3.7, 3.8, 3.9, 3.10, 3.11\n- Django 3.2, 4.0, 4.1\n\n## Installation\n\nInstallation is easy using `pip` and will install all required\nlibraries.\n```bash\n$ pip install django-notifications-hq\n```\nor get it from source\n\n```bash\n$ git clone https://github.com/django-notifications/django-notifications\n$ cd django-notifications\n$ python setup.py sdist\n$ pip install dist/django-notifications-hq*\n```\n\nNote that [django-model-utils](http://pypi.python.org/pypi/django-model-utils)\nwill be installed: this is required for the pass-through QuerySet manager.\n\nThen to add the Django Notifications to your project add the app\n`notifications` to your `INSTALLED_APPS` and urlconf.\n\nThe app should go somewhere after all the apps that are going to be\ngenerating notifications like `django.contrib.auth`\n\n```python\nINSTALLED_APPS = (\n 'django.contrib.auth',\n ...\n 'notifications',\n ...\n)\n```\n\nAdd the notifications urls to your urlconf:\n\n```python\nurlpatterns = [\n ...\n path('inbox/notifications/', include('notifications.urls', namespace='notifications')),\n ...\n]\n```\n\nTo run schema migration, execute\n`python manage.py migrate notifications`.\n\n## Generating Notifications\n\nGenerating notifications is probably best done in a separate signal.\n\n```python\nfrom django.db.models.signals import post_save\nfrom notifications.signals import notify\nfrom myapp.models import MyModel\n\ndef my_handler(sender, instance, created, **kwargs):\n notify.send(instance, verb='was saved')\n\npost_save.connect(my_handler, sender=MyModel)\n```\nTo generate an notification anywhere in your code, simply import the\nnotify signal and send it with your actor, recipient, and verb.\n\n```python\nfrom notifications.signals import notify\n\nnotify.send(user, recipient=user, verb='you reached level 10')\n```\n\nThe complete syntax is.\n\n```python\nnotify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)\n```\n\nArguments:\n\n- **actor**: An object of any type. (Required) Note: Use\n **sender** instead of **actor** if you intend to use keyword\n arguments\n- **recipient**: A **Group** or a **User QuerySet** or a list of\n **User**. (Required)\n- **verb**: An string. (Required)\n- **action\\_object**: An object of any type. (Optional)\n- **target**: An object of any type. (Optional)\n- **level**: One of Notification.LEVELS (\\'success\\', \\'info\\',\n \\'warning\\', \\'error\\') (default=info). (Optional)\n- **description**: An string. (Optional)\n- **public**: An boolean (default=True). (Optional)\n- **timestamp**: An tzinfo (default=timezone.now()). (Optional)\n\n### Extra data\n\nYou can attach arbitrary data to your notifications by doing the\nfollowing:\n\n- Add to your settings.py:\n `DJANGO_NOTIFICATIONS_CONFIG = { 'USE_JSONFIELD': True}`\n\nThen, any extra arguments you pass to `notify.send(...)` will be\nattached to the `.data` attribute of the notification object. These will\nbe serialised using the JSONField\\'s serialiser, so you may need to take\nthat into account: using only objects that will be serialised is a good\nidea.\n\n### Soft delete\n\nBy default, `delete/(?P<slug>\\d+)/` deletes specified notification\nrecord from DB. You can change this behaviour to \\\"mark\n`Notification.deleted` field as `True`\\\" by:\n\n- Add to your settings.py:\n `DJANGO_NOTIFICATIONS_CONFIG = { 'SOFT_DELETE': True}`\n\nWith this option, QuerySet methods `unread` and `read` contain one more\nfilter: `deleted=False`. Meanwhile, QuerySet methods `deleted`,\n`active`, `mark_all_as_deleted`, `mark_all_as_active` are turned on. See\nmore details in QuerySet methods section.\n\n## API\n\n### QuerySet methods\n\nUsing `django-model-utils`, we get the ability to add queryset methods\nto not only the manager, but to all querysets that will be used,\nincluding related objects. This enables us to do things like:\n\n```python\n Notification.objects.unread()\n```\n\nwhich returns all unread notifications. To do this for a single user, we\ncan do:\n\n```python\n user = User.objects.get(pk=pk)\n user.notifications.unread()\n```\n\nThere are some other QuerySet methods, too.\n\n#### `qs.unsent()`\n\nReturn all of the unsent notifications, filtering the current queryset.\n(emailed=False)\n\n#### `qs.sent()`\n\nReturn all of the sent notifications, filtering the current queryset.\n(emailed=True)\n\n#### `qs.unread()`\n\nReturn all of the unread notifications, filtering the current queryset.\nWhen `SOFT_DELETE=True`, this filter contains `deleted=False`.\n\n#### `qs.read()`\n\nReturn all of the read notifications, filtering the current queryset.\nWhen `SOFT_DELETE=True`, this filter contains `deleted=False`.\n\n#### `qs.mark_all_as_read()` \\| `qs.mark_all_as_read(recipient)`\n\nMark all of the unread notifications in the queryset (optionally also\nfiltered by `recipient`) as read.\n\n#### `qs.mark_all_as_unread()` \\| `qs.mark_all_as_unread(recipient)`\n\nMark all of the read notifications in the queryset (optionally also\nfiltered by `recipient`) as unread.\n\n#### `qs.mark_as_sent()` \\| `qs.mark_as_sent(recipient)`\n\nMark all of the unsent notifications in the queryset (optionally also\nfiltered by `recipient`) as sent.\n\n#### `qs.mark_as_unsent()` \\| `qs.mark_as_unsent(recipient)`\n\nMark all of the sent notifications in the queryset (optionally also\nfiltered by `recipient`) as unsent.\n\n#### `qs.deleted()`\n\nReturn all notifications that have `deleted=True`, filtering the current\nqueryset. Must be used with `SOFT_DELETE=True`.\n\n#### `qs.active()`\n\nReturn all notifications that have `deleted=False`, filtering the\ncurrent queryset. Must be used with `DELETE=True`.\n\n#### `qs.mark_all_as_deleted()` \\| `qs.mark_all_as_deleted(recipient)`\n\nMark all notifications in the queryset (optionally also filtered by\n`recipient`) as `deleted=True`. Must be used with `DELETE=True`.\n\n#### `qs.mark_all_as_active()` \\| `qs.mark_all_as_active(recipient)`\n\nMark all notifications in the queryset (optionally also filtered by\n`recipient`) as `deleted=False`. Must be used with `SOFT_DELETE=True`.\n\n### Model methods\n\n#### `obj.timesince([datetime])`\n\nA wrapper for Django\\'s `timesince` function.\n\n#### `obj.mark_as_read()`\n\nMark the current object as read.\n\n### Template tags\n\nPut `{% load notifications_tags %}` in the template before\nyou actually use notification tags.\n\n### `notifications_unread`\n\n```python\n {% notifications_unread %}\n```\n\nGive the number of unread notifications for a user, or nothing (an empty\nstring) for an anonymous user.\n\nStoring the count in a variable for further processing is advised, such\nas:\n\n```python\n {% notifications_unread as unread_count %}\n ...\n {% if unread_count %}\n You have <strong>{{ unread_count }}</strong> unread notifications.\n {% endif %}\n```\n\n## Live-updater API\n\nTo ensure users always have the most up-to-date notifications,\n`django-notifications` includes a simple javascript API for\nupdating specific fields within a django template.\n\nThere are two possible API calls that can be made:\n\n1. `api/unread_count/` that returns a javascript object with 1 key:\n `unread_count` eg:\n\n {\"unread_count\":1}\n\n2. `api/unread_list/` that returns a javascript object with 2 keys:\n `unread_count` and `unread_list` eg:\n\n {\n \"unread_count\":1,\n \"unread_list\":[--list of json representations of notifications--]\n }\n\n Representations of notifications are based on the django method:\n `model_to_dict`\n\n Query string arguments:\n\n - **max** - maximum length of unread list.\n - **mark\\_as\\_read** - mark notification in list as read.\n\n For example, get `api/unread_list/?max=3&mark_as_read=true` returns\n 3 notifications and mark them read (remove from list on next\n request).\n\n The list outputs `target_url`, `actor_url`, `action_object_url`.\n This URL is generated from standard Django `Model.get_absolute_url()` or\n you can override the URL just for notifications by implementing\n `Model.get_url_for_notifications(notification, request)`.\n\n### How to use:\n\n1. Put `{% load notifications_tags %}` in the template before you\n actually use notification tags.\n\n2. In the area where you are loading javascript resources add the\n following tags in the order below:\n\n <script src=\"{% static 'notifications/notify.js' %}\" type=\"text/javascript\"></script>\n {% register_notify_callbacks callbacks='fill_notification_list,fill_notification_badge' %}\n\n `register_notify_callbacks` takes the following arguments:\n\n 1. `badge_class` (default `live_notify_badge`) - The identifier\n `class` of the element to show the unread count,\n that will be periodically updated.\n 2. `menu_class` (default `live_notify_list`) - The identifier\n `class` of the element to insert a list of unread\n items, that will be periodically updated.\n 3. `refresh_period` (default `15`) - How often to fetch unread\n items from the server (integer in seconds).\n 4. `fetch` (default `5`) - How many notifications to fetch each\n time.\n 5. `callbacks` (default `<empty string>`) - A comma-separated list\n of javascript functions to call each period.\n 6. `api_name` (default `list`) - The name of the API to call (this\n can be either `list` or `count`).\n 7. ``mark_as_read`` (default ``False``) - Marks notifications as read when fetched.\n\n3. To insert a live-updating unread count, use the following template:\n\n {% live_notify_badge %}\n\n `live_notify_badge` takes the following arguments:\n\n - `badge_class` (default `live_notify_badge`) - The identifier\n `class` for the `<span>` element that will be created to show\n the unread count.\n\n4. To insert a live-updating unread list, use the following template:\n\n {% live_notify_list %}\n\n `live_notify_list` takes the following arguments:\n\n - `list_class` (default `live_notify_list`) - The identifier\n `class` for the `<ul>` element that will be created to insert\n the list of notifications into.\n\n### Using the live-updater with bootstrap\n\nThe Live-updater can be incorporated into bootstrap with minimal code.\n\nTo create a live-updating bootstrap badge containing the unread count,\nsimply use the template tag:\n\n {% live_notify_badge badge_class=\"badge\" %}\n\nTo create a live-updating bootstrap dropdown menu containing a selection\nof recent unread notifications, simply use the template tag:\n\n {% live_notify_list list_class=\"dropdown-menu\" %}\n\n### Customising the display of notifications using javascript callbacks\n\nWhile the live notifier for unread counts should suit most use cases,\nusers may wish to alter how unread notifications are shown.\n\nThe `callbacks` argument of the `register_notify_callbacks` dictates\nwhich javascript functions are called when the unread api call is made.\n\nTo add a custom javascript callback, simply add this to the list, like\nso:\n\n {% register_notify_callbacks callbacks='fill_notification_badge,my_special_notification_callback' %}\n\nThe above would cause the callback to update the unread count badge, and\nwould call the custom function\n`my_special_notification_callback`. All callback\nfunctions are passed a single argument by convention called\n`data`, which contains the entire result from the API.\n\nFor example, the below function would get the recent list of unread\nmessages and log them to the console:\n\n```javascript\nfunction my_special_notification_callback(data) {\n for (var i=0; i < data.unread_list.length; i++) {\n msg = data.unread_list[i];\n console.log(msg);\n }\n}\n```\n\n### Testing the live-updater\n\n1. Clone the repo\n2. Run `./manage.py runserver`\n3. Browse to `yourserverip/test/`\n4. Click \\'Make a notification\\' and a new notification should appear\n in the list in 5-10 seconds.\n\n## Serializing the django-notifications Model\n\nSee here - <http://www.django-rest-framework.org/api-guide/relations/#generic-relationships>\n\nIn this example the target object can be of type Foo or Bar and the\nappropriate serializer will be used.\n\n```python\nclass GenericNotificationRelatedField(serializers.RelatedField):\n\n def to_representation(self, value):\n if isinstance(value, Foo):\n serializer = FooSerializer(value)\n if isinstance(value, Bar):\n serializer = BarSerializer(value)\n\n return serializer.data\n\n\nclass NotificationSerializer(serializers.Serializer):\n recipient = PublicUserSerializer(User, read_only=True)\n unread = serializers.BooleanField(read_only=True)\n target = GenericNotificationRelatedField(read_only=True)\n```\n\nThanks to @DaWy\n\n### `AbstractNotification` model\n\nIn case you need to customize the notification model in order to add\nfield or customised features that depend on your application, you can\ninherit and extend the `AbstractNotification` model, example:\n\n```python\n#In your_app/models.py\n\nfrom django.db import models\nfrom notifications.base.models import AbstractNotification\n\n\nclass Notification(AbstractNotification):\n # custom field example\n category = models.ForeignKey('myapp.Category',\n on_delete=models.CASCADE)\n\n class Meta(AbstractNotification.Meta):\n abstract = False\n```\n\nYou will require to define `NOTIFICATIONS_NOTIFICATION_MODEL` setting in\n`setting.py` as follows:\n\n```python\n# In your_project/settings.py\n\nNOTIFICATIONS_NOTIFICATION_MODEL = 'your_app.Notification'\n```\n\n## Notes\n\n### Email Notification\n\nSending email to users has not been integrated into this library. So for\nnow you need to implement it if needed. There is a reserved field\n`Notification.emailed` to make it easier.\n\n### Sample App\n\nA sample app has been implemented in\n`notifications/tests/sample_notifications` that extends\n`django-notifications` with the sole purpose of testing its\nextensibility. You can run the SAMPLE APP by setting the environment\nvariable `SAMPLE_APP` as follows\n\n```bash\nexport SAMPLE_APP=1\n# Run the Django development server with sample_notifications app installed\npython manage.py runserver\n# Unset SAMPLE_APP to remove sample_notifications app from list of INSTALLED_APPS\nunset SAMPLE_APP\n```\n\n## `django-notifications` Team\n\nCore contributors (in alphabetical order):\n\n- [Alvaro Leonel](https://github.com/AlvaroLQueiroz)\n- [Federico Capoano](https://github.com/nemesisdesign)\n- [Samuel Spencer](https://github.com/LegoStormtroopr)\n- [Yang Yubo](https://github.com/yangyubo)\n- [YPCrumble](https://github.com/YPCrumble)\n- [Zhongyuan Zhang](https://github.com/zhang-z)\n\n## Contribute\n\nWe are looking for contributors, for anyone who\\'d like to contribute\nand willing to put time and energy on this project, please contact [Yang\nYubo](https://github.com/yangyubo).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "GitHub notifications alike app for Django with expo push notifications",
"version": "1.8.0",
"project_urls": {
"Homepage": "https://github.com/nachoborrelli/django-notifications"
},
"split_keywords": [
"django",
"notifications",
"github",
"action",
"event",
"stream",
"expo",
"push",
"viewset",
"cron",
"crontab"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "299f9c3e66690bdc14eacd5a0bb9d6c21edcbe36334fcab2a3543baea3c8e5fa",
"md5": "74c513433559886ffafd57774c9fd2cd",
"sha256": "35c3f32b972ab255d7438434a42e356e63889af254610d81b011877a2a23b808"
},
"downloads": -1,
"filename": "django_notifications_pro-1.8.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "74c513433559886ffafd57774c9fd2cd",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 43581,
"upload_time": "2024-10-21T12:27:10",
"upload_time_iso_8601": "2024-10-21T12:27:10.342023Z",
"url": "https://files.pythonhosted.org/packages/29/9f/9c3e66690bdc14eacd5a0bb9d6c21edcbe36334fcab2a3543baea3c8e5fa/django_notifications_pro-1.8.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4268ec85c2be78f65cd0b0646acc2f81c6f5f1b12e068638a7ffe054d2ba72ef",
"md5": "ca4dd64c78bfcb29190f8fcdfd11b751",
"sha256": "93a9a5795f8c1ccb9789758992f77832c72c578ae079e1ea23029bcdfe35e39a"
},
"downloads": -1,
"filename": "django_notifications_pro-1.8.0.tar.gz",
"has_sig": false,
"md5_digest": "ca4dd64c78bfcb29190f8fcdfd11b751",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 36392,
"upload_time": "2024-10-21T12:27:12",
"upload_time_iso_8601": "2024-10-21T12:27:12.495081Z",
"url": "https://files.pythonhosted.org/packages/42/68/ec85c2be78f65cd0b0646acc2f81c6f5f1b12e068638a7ffe054d2ba72ef/django_notifications_pro-1.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-21 12:27:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "nachoborrelli",
"github_project": "django-notifications",
"travis_ci": true,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "django-notifications-pro"
}