<commit_before>``django-notifications`` Documentation
=======================================


|build-status| |coveralls|

`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 2.7, 3.3, 3.4, 3.5
- Django 1.7, 1.8, 1.9, 1.10

Installation
============

Installation is easy using ``pip`` and will install all required libraries.

::

    $ pip install django-notifications-hq

or get it from source

::

    $ git clone https://github.com/django-notifications/django-notifications
    $ cd django-notifications
    $ python setup.py install

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``

::

    INSTALLED_APPS = (
        'django.contrib.auth',
        ...
        'notifications',
        ...
    )

Add the notifications urls to your urlconf::

    import notifications.urls

    urlpatterns = [
        ...
        url('^inbox/notifications/', include(notifications.urls, namespace='notifications')),
        ...
    ]

The method of installing these urls, importing rather than using ``'notifications.urls'``, is required to ensure that the urls are installed in the ``notifications`` namespace.

To run schema migration, execute ``python manage.py migrate notifications``.

Generating Notifications
=========================

Generating notifications is probably best done in a separate signal.

::

    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.

::

    from notifications.signals import notify

    notify.send(user, recipient=user, verb='you reached level 10')

The complete syntax is.

::

    notify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)

Arguments:
 * **actor**: An object of any type. (Required)
 * **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: ``NOTIFICATIONS_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: ``NOTIFICATIONS_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::

  Notification.objects.unread()

which returns all unread notifications. To do this for a single user, we can do::

  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.read()``
~~~~~~~~~~~~~~~

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 ``NOTIFICATIONS_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``.


``qs.mark_all_as_read()`` | ``qs.mark_all_as_read(recipient)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<commit_msg>modify 'qs.read' to 'qs.sent'<commit_after>``django-notifications`` Documentation
=======================================


|build-status| |coveralls|

`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 2.7, 3.3, 3.4, 3.5
- Django 1.7, 1.8, 1.9, 1.10

Installation
============

Installation is easy using ``pip`` and will install all required libraries.

::

    $ pip install django-notifications-hq

or get it from source

::

    $ git clone https://github.com/django-notifications/django-notifications
    $ cd django-notifications
    $ python setup.py install

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``

::

    INSTALLED_APPS = (
        'django.contrib.auth',
        ...
        'notifications',
        ...
    )

Add the notifications urls to your urlconf::

    import notifications.urls

    urlpatterns = [
        ...
        url('^inbox/notifications/', include(notifications.urls, namespace='notifications')),
        ...
    ]

The method of installing these urls, importing rather than using ``'notifications.urls'``, is required to ensure that the urls are installed in the ``notifications`` namespace.

To run schema migration, execute ``python manage.py migrate notifications``.

Generating Notifications
=========================

Generating notifications is probably best done in a separate signal.

::

    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.

::

    from notifications.signals import notify

    notify.send(user, recipient=user, verb='you reached level 10')

The complete syntax is.

::

    notify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)

Arguments:
 * **actor**: An object of any type. (Required)
 * **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: ``NOTIFICATIONS_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: ``NOTIFICATIONS_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::

  Notification.objects.unread()

which returns all unread notifications. To do this for a single user, we can do::

  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 ``NOTIFICATIONS_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``.


``qs.mark_all_as_read()`` | ``qs.mark_all_as_read(recipient)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

{'fraction_non_alphanumeric': 0.15308419630796938, 'fraction_numerical': 0.0037520636349992497, 'mean_word_length': 4.566833751044277, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6660728', 'n_tokens_mistral': 3779, 'n_tokens_neox': 3624, 'n_words': 1393}