Django Push Notifications
django-push-notifications is a Django library for sending push notifications to mobile devices via services like FCM (Firebase Cloud Messaging), APNS (Apple Push Notification service), and to WebPush-enabled browsers (Chrome, Firefox, Opera). It simplifies device registration and message sending within a Django project. The current version is 3.3.0, and the project maintains an active release cadence with regular updates.
Common errors
-
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
cause `push_notifications` is not listed in `INSTALLED_APPS` or Django's app registry has not initialized when models are accessed.fixAdd `'push_notifications'` to your `INSTALLED_APPS` in `settings.py`. Ensure any code interacting with `push_notifications` models runs within a properly initialized Django environment (e.g., within a Django management command or web request). -
KeyError: 'APNS_AUTH_KEY_PATH' or ImproperlyConfigured: The GCM_API_KEY must be set in PUSH_NOTIFICATIONS_SETTINGS.
cause Required push service credentials (e.g., APNS key path, FCM API key) are missing from the `PUSH_NOTIFICATIONS_SETTINGS` dictionary in your `settings.py`.fixProvide all necessary `PUSH_NOTIFICATIONS_SETTINGS` in your Django `settings.py` as outlined in the `django-push-notifications` documentation for each service (APNS, FCM/GCM, WebPush). -
TypeError: 'bool' object is not subscriptable (when sending APNS mutable_content)
cause In `django-push-notifications` versions 3.2.1 and later, the `mutable_content` parameter for APNS requires an integer (1 or 0) instead of a boolean (True or False).fixUpdate your APNS `send_message` calls to use `mutable_content=1` or `mutable_content=0` instead of `mutable_content=True` or `mutable_content=False`. -
ImportError: cannot import name 'gcm_send_message' from 'push_notifications.gcm'
cause Direct utility functions like `gcm_send_message` (and similar for APNS) are considered legacy. The recommended way to send messages is via the `send_message` method on `GCMDevice` (or `APNSDevice`, `WebPushDevice`) instances.fixInstead of importing and using `gcm_send_message`, retrieve a `GCMDevice` object and call its `send_message` method: `from push_notifications.models import GCMDevice; device = GCMDevice.objects.get(pk=1); device.send_message('Hello!')`.
Warnings
- breaking The `aioapns` dependency was pinned to `<4.0` in `django-push-notifications` version 3.3.0 to prevent breaking changes introduced in `aioapns` v4. If you have `aioapns` v4 installed, this could lead to import errors or unexpected behavior.
- breaking The `mutable_content` field type for APNS messages changed from boolean `True` to integer `1` (or `0` for `False`) in version 3.2.1. Passing a boolean will raise a `TypeError`.
- gotcha Version 3.3.0 introduced an explicit Django `AppConfig` and sets `default_auto_field`. For older Django versions (pre-3.2) or custom configurations, you might encounter `AutoField` related warnings if `DEFAULT_AUTO_FIELD` is not explicitly set in your Django project.
- deprecated FCM v1 API support was added in version 3.1.0. The legacy GCM API is deprecated by Google and may be removed in future `django-push-notifications` versions. It is highly recommended to migrate to FCM v1.
- breaking Support for Python versions less than 3.4 was dropped in version 1.4.0. The library currently requires Python 3.7+.
Install
-
pip install django-push-notifications
Imports
- GCMDevice
from push_notifications.models import GCMDevice
- APNSDevice
from push_notifications.models import APNSDevice
- WebPushDevice
from push_notifications.models import WebPushDevice
Quickstart
import os
from django.conf import settings
from django.apps import apps
from push_notifications.models import GCMDevice, APNSDevice
# --- Minimal Django settings for standalone execution ---
# In a real Django project, these settings would be in your settings.py
# and you would simply import and use the Device models after Django is initialized.
if not apps.ready:
settings.configure(
INSTALLED_APPS=[
'django.contrib.auth',
'django.contrib.contenttypes',
'push_notifications'
],
# Minimal database settings for demo
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
PUSH_NOTIFICATIONS_SETTINGS={
"APNS_AUTH_KEY_PATH": os.environ.get("APNS_AUTH_KEY_PATH", "/path/to/apns_key.p8"),
"APNS_AUTH_KEY_ID": os.environ.get("APNS_AUTH_KEY_ID", "YOUR_APNS_KEY_ID"),
"APNS_TEAM_ID": os.environ.get("APNS_TEAM_ID", "YOUR_APNS_TEAM_ID"),
"APNS_APP_ID": os.environ.get("APNS_APP_ID", "com.example.app"),
"GCM_API_KEY": os.environ.get("GCM_API_KEY", "YOUR_LEGACY_FCM_SERVER_KEY"), # For legacy GCM
"FCM_API_KEY": os.environ.get("FCM_API_KEY", "/path/to/fcm_v1_credentials.json"), # For FCM v1
},
DEFAULT_AUTO_FIELD='django.db.models.BigAutoField', # Recommended for Django 3.2+
)
apps.populate(settings.INSTALLED_APPS)
# --- End of minimal Django settings ---
print("Registering a GCM (FCM) device and sending a message...")
# Replace 'your_fcm_device_token' with an actual device token
device_gcm, created_gcm = GCMDevice.objects.get_or_create(
registration_id="your_fcm_device_token",
active=True,
user=None # Link to a Django User object if applicable
)
if created_gcm:
print(f"Created new GCM device: {device_gcm}")
else:
print(f"Found existing GCM device: {device_gcm}")
try:
response_gcm = device_gcm.send_message(
"Hello from FCM!",
badge=1,
extra={"custom_data": "value"}
)
print(f"FCM message sent. Response: {response_gcm}")
except Exception as e:
print(f"Error sending FCM message: {e}")
print("\nRegistering an APNS device and sending a message...")
# Replace 'your_apns_device_token' with an actual device token
device_apns, created_apns = APNSDevice.objects.get_or_create(
registration_id="your_apns_device_token",
active=True,
user=None
)
if created_apns:
print(f"Created new APNS device: {device_apns}")
else:
print(f"Found existing APNS device: {device_apns}")
try:
response_apns = device_apns.send_message(
message="Hello from APNS!",
badge=1,
sound="default",
category="my_category",
mutable_content=1, # Note: integer 1 or 0 for >=3.2.1
extra={"custom_data": "value"}
)
print(f"APNS message sent. Response: {response_apns}")
except Exception as e:
print(f"Error sending APNS message: {e}")
# For WebPush, you would typically handle subscription via JavaScript in the frontend
# and then create/use a WebPushDevice instance similarly to send notifications.