Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

GitHub notifications alike app for Django

License

NotificationsYou must be signed in to change notification settings

django-notifications/django-notifications

Repository files navigation

build-statusCoverage Status

django-notifications is a GitHub notification alike app for Django, it was derived fromdjango-activity-stream

The major difference betweendjango-notifications anddjango-activity-stream:

  • django-notifications is for building something like Github "Notifications"
  • Whiledjango-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 actionitself.
  • Target.(Optional) The object to which the activity wasperformed.

Actor,Action Object andTarget areGenericForeignKeys to anyarbitrary Django object. An action is a description of an action thatwas performed (Verb) at some instant in time by someActor on someoptionalTarget that results in anAction Object gettingcreated/updated/deleted.

For example:justquick(actor)closed(verb)issue2(action_object) onactivity-stream(target) 12 hours ago

Nomenclature of this specification is based on the Activity StreamsSpec: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 usingpip and will install all requiredlibraries.

$ 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 sdist$ pip install dist/django-notifications-hq*

Note thatdjango-model-utilswill be installed: this is required for the pass-through QuerySet manager.

Then to add the Django Notifications to your project add the appnotifications to yourINSTALLED_APPS and urlconf.

The app should go somewhere after all the apps that are going to begenerating notifications likedjango.contrib.auth

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

Add the notifications urls to your urlconf:

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

To run schema migration, executepython manage.py migrate notifications.

Generating Notifications

Generating notifications is probably best done in a separate signal.

fromdjango.db.models.signalsimportpost_savefromnotifications.signalsimportnotifyfrommyapp.modelsimportMyModeldefmy_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 thenotify signal and send it with your actor, recipient, and verb.

fromnotifications.signalsimportnotifynotify.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) Note: Usesender instead ofactor if you intend to use keywordarguments
  • recipient: AGroup or aUser QuerySet or a list ofUser. (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 thefollowing:

  • Add to your settings.py:DJANGO_NOTIFICATIONS_CONFIG = { 'USE_JSONFIELD': True}

Then, any extra arguments you pass tonotify.send(...) will beattached to the.data attribute of the notification object. These willbe serialised using the JSONField's serialiser, so you may need to takethat into account: using only objects that will be serialised is a goodidea.

Soft delete

By default,delete/(?P<slug>\d+)/ deletes specified notificationrecord from DB. You can change this behaviour to "markNotification.deleted field asTrue" by:

  • Add to your settings.py:DJANGO_NOTIFICATIONS_CONFIG = { 'SOFT_DELETE': True}

With this option, QuerySet methodsunread andread contain one morefilter:deleted=False. Meanwhile, QuerySet methodsdeleted,active,mark_all_as_deleted,mark_all_as_active are turned on. Seemore details in QuerySet methods section.

API

QuerySet methods

Usingdjango-model-utils, we get the ability to add queryset methodsto 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, wecan 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.WhenSOFT_DELETE=True, this filter containsdeleted=False.

qs.read()

Return all of the read notifications, filtering the current queryset.WhenSOFT_DELETE=True, this filter containsdeleted=False.

qs.mark_all_as_read() |qs.mark_all_as_read(recipient)

Mark all of the unread notifications in the queryset (optionally alsofiltered byrecipient) as read.

qs.mark_all_as_unread() |qs.mark_all_as_unread(recipient)

Mark all of the read notifications in the queryset (optionally alsofiltered byrecipient) as unread.

qs.mark_as_sent() |qs.mark_as_sent(recipient)

Mark all of the unsent notifications in the queryset (optionally alsofiltered byrecipient) as sent.

qs.mark_as_unsent() |qs.mark_as_unsent(recipient)

Mark all of the sent notifications in the queryset (optionally alsofiltered byrecipient) as unsent.

qs.deleted()

Return all notifications that havedeleted=True, filtering the currentqueryset. Must be used withSOFT_DELETE=True.

qs.active()

Return all notifications that havedeleted=False, filtering thecurrent queryset. Must be used withDELETE=True.

qs.mark_all_as_deleted() |qs.mark_all_as_deleted(recipient)

Mark all notifications in the queryset (optionally also filtered byrecipient) asdeleted=True. Must be used withDELETE=True.

qs.mark_all_as_active() |qs.mark_all_as_active(recipient)

Mark all notifications in the queryset (optionally also filtered byrecipient) asdeleted=False. Must be used withSOFT_DELETE=True.

Model methods

obj.timesince([datetime])

A wrapper for Django'stimesince function.

obj.mark_as_read()

Mark the current object as read.

Template tags

Put{% load notifications_tags %} in the template beforeyou actually use notification tags.

notifications_unread

    {%notifications_unread%}

Give the number of unread notifications for a user, or nothing (an emptystring) for an anonymous user.

Storing the count in a variable for further processing is advised, suchas:

    {%notifications_unreadasunread_count%}    ...    {%ifunread_count%}Youhave<strong>{{unread_count }}</strong>unreadnotifications.    {%endif%}

Live-updater API

To ensure users always have the most up-to-date notifications,django-notifications includes a simple javascript API forupdating 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 andunread_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, getapi/unread_list/?max=3&mark_as_read=true returns3 notifications and mark them read (remove from list on nextrequest).

    The list outputstarget_url,actor_url,action_object_url.This URL is generated from standard DjangoModel.get_absolute_url() oryou can override the URL just for notifications by implementingModel.get_url_for_notifications(notification, request).

How to use:

  1. Put{% load notifications_tags %} in the template before youactually use notification tags.

  2. In the area where you are loading javascript resources add thefollowing 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 (defaultlive_notify_badge) - The identifierclass of the element to show the unread count,that will be periodically updated.
    2. menu_class (defaultlive_notify_list) - The identifierclass of the element to insert a list of unreaditems, that will be periodically updated.
    3. refresh_period (default15) - How often to fetch unreaditems from the server (integer in seconds).
    4. fetch (default5) - How many notifications to fetch eachtime.
    5. callbacks (default<empty string>) - A comma-separated listof javascript functions to call each period.
    6. api_name (defaultlist) - The name of the API to call (thiscan be eitherlist orcount).
    7. mark_as_read (defaultFalse) - 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 (defaultlive_notify_badge) - The identifierclass for the<span> element that will be created to showthe 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 (defaultlive_notify_list) - The identifierclass for the<ul> element that will be created to insertthe 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 selectionof 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.

Thecallbacks argument of theregister_notify_callbacks dictateswhich javascript functions are called when the unread api call is made.

To add a custom javascript callback, simply add this to the list, likeso:

{% register_notify_callbacks callbacks='fill_notification_badge,my_special_notification_callback' %}

The above would cause the callback to update the unread count badge, andwould call the custom functionmy_special_notification_callback. All callbackfunctions are passed a single argument by convention calleddata, which contains the entire result from the API.

For example, the below function would get the recent list of unreadmessages and log them to the console:

functionmy_special_notification_callback(data){for(vari=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 toyourserverip/test/
  4. Click 'Make a notification' and a new notification should appearin 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 theappropriate serializer will be used.

classGenericNotificationRelatedField(serializers.RelatedField):defto_representation(self,value):ifisinstance(value,Foo):serializer=FooSerializer(value)ifisinstance(value,Bar):serializer=BarSerializer(value)returnserializer.dataclassNotificationSerializer(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 addfield or customised features that depend on your application, you caninherit and extend theAbstractNotification model, example:

#In your_app/models.pyfromdjango.dbimportmodelsfromnotifications.base.modelsimportAbstractNotificationclassNotification(AbstractNotification):# custom field examplecategory=models.ForeignKey('myapp.Category',on_delete=models.CASCADE)classMeta(AbstractNotification.Meta):abstract=False

You will require to defineNOTIFICATIONS_NOTIFICATION_MODEL setting insetting.py as follows:

# In your_project/settings.pyNOTIFICATIONS_NOTIFICATION_MODEL='your_app.Notification'

Notes

Email Notification

Sending email to users has not been integrated into this library. So fornow you need to implement it if needed. There is a reserved fieldNotification.emailed to make it easier.

Sample App

A sample app has been implemented innotifications/tests/sample_notifications that extendsdjango-notifications with the sole purpose of testing itsextensibility. You can run the SAMPLE APP by setting the environmentvariableSAMPLE_APP as follows

export SAMPLE_APP=1# Run the Django development server with sample_notifications app installedpython manage.py runserver# Unset SAMPLE_APP to remove sample_notifications app from list of INSTALLED_APPSunset SAMPLE_APP

django-notifications Team

Core contributors (in alphabetical order):

Contribute

We are looking for contributors, for anyone who'd like to contributeand willing to put time and energy on this project, please contactYangYubo.


[8]ページ先頭

©2009-2025 Movatter.jp