介绍
网络不断发展,现在可以实现以前只能在本机移动设备上使用的功能。JavaScript 服务工作者的引入为Web提供了新的功能,可以执行后台同步,脱机缓存和发送推送通知等功能。
推送通知允许用户选择接收移动和Web应用程序的更新。它们还使用户能够使用自定义和相关内容重新使用现有应用程序。
在本教程中,您将在Ubuntu 18.04上设置一个Django应用程序,只要有需要用户访问应用程序的活动,就会发送推送通知。要创建这些通知,您将使用Django-Webpush包并设置和注册服务工作者以向客户端显示通知。带通知的工作应用程序如下所示:
先决条件
在开始本指南之前,您需要以下内容:
- 一个Ubuntu 18.04服务器,具有非root用户和活动防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。
- 遵循这些准则安装
pip
和venv
。 - 在您的主目录中创建一个名为
djangopush
的项目,按照这些关于在Ubuntu上创建示例Django项目的指南进行设置。务必将服务器的IP地址添加到settings.py
文件中ALLOWED_HOSTS
的指令中。
第1步 - 安装Django-Webpush并获取Vapid密钥
Django-Webpush是一个允许开发人员在Django应用程序中集成和发送Web推送通知的软件包。我们将使用此包来触发和发送来自我们应用程序的推送通知。在此步骤中,您将安装Django-Webpush并获取识别服务器所需的自愿应用程序服务器标识(VAPID)密钥,并确保每个请求的唯一性。
确保您位于先决条件中创建的~/djangopush
项目目录中:
cd ~/djangopush
激活您的虚拟环境:
代码语言:javascript复制source my_env/bin/activate
升级您的pip
版本以确保它是最新的:
pip install --upgrade pip
安装Django-Webpush:
代码语言:javascript复制pip install django-webpush
安装软件包后,将其添加到settings.py
文件中的应用程序列表中。首先打开settings.py
:
nano ~/djangopush/djangopush/settings.py
添加webpush
到以下INSTALLED_APPS
列表中:
...
INSTALLED_APPS = [
...,
'webpush',
]
...
保存文件并退出编辑器。
在应用程序上运行迁移以应用您对数据库模式所做的更改:
代码语言:javascript复制python manage.py migrate
输出将如下所示,表示迁移成功:
代码语言:javascript复制Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, webpush
Running migrations:
Applying webpush.0001_initial... OK
设置Web推送通知的下一步是获取VAPID密钥。这些密钥标识应用程序服务器,可用于减少推送订阅URL的保密性,因为它们限制对特定服务器的订阅。
要获取VAPID密钥,请导航到wep-push-codelab Web应用程序。在这里,您将获得自动生成的密钥。复制私钥和公钥。
接下来,在settings.py
中为您的VAPID信息创建一个新条目。首先,打开文件:
nano ~/djangopush/djangopush/settings.py
接下来,使用您的VAPID公钥和私钥创建一个名为WEBPUSH_SETTINGS
的新指令以及在下AUTH_PASSWORD_VALIDATORS
面的电子邮件:
...
AUTH_PASSWORD_VALIDATORS = [
...
]
WEBPUSH_SETTINGS = {
"VAPID_PUBLIC_KEY": "your_vapid_public_key",
"VAPID_PRIVATE_KEY": "your_vapid_private_key",
"VAPID_ADMIN_EMAIL": "admin@example.com"
}
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
...
不要忘了使用自己的信息替换值为your_vapid_public_key
,your_vapid_private_key
以及admin@example.com
的占位符。如果推送服务器遇到任何问题,您的电子邮件地址就是通知您的方式。
接下来,我们将设置视图,以显示应用程序的主页并向订阅用户触发推送通知。
第2步 - 设置视图
在此步骤中,我们将使用HttpResponse
响应对象来设置基本的home
视图和send_push
视图。视图是从Web请求返回响应对象的函数。该 send_push
视图将使用Django-Webpush库发送包含用户在主页上输入的数据的推送通知。
导航到该~/djangopush/djangopush
文件夹:
cd ~/djangopush/djangopush
在文件夹内运行ls
将显示项目的主文件:
/__init__.py
/settings.py
/urls.py
/wsgi.py
此文件夹中的文件由您用于在先决条件中创建项目的django-admin
实用程序自动生成。该settings.py
文件包含项目范围的配置,如已安装的应用程序和静态根文件夹。该urls.py
文件包含项目的URL配置。您可以在此处设置路线以匹配您创建的视图。
在~/djangopush/djangopush
目录中创建一个名为 views.py
的新文件,该文件将包含项目的视图:
nano ~/djangopush/djangopush/views.py
我们要做的第一个视图是home
视图,它将显示用户可以发送推送通知的主页。将以下代码添加到文件中:
from django.http.response import HttpResponse
from django.views.decorators.http import require_GET
@require_GET
def home(request):
return HttpResponse('<h1>Home Page<h1>')
该home
视图是由require_GET
装饰,其中规定只有GET请求的观点。视图通常会为每个请求返回响应。此视图返回一个简单的HTML标记作为响应。
我们将创建的下一个视图是send_push
,它将处理使用该django-webpush
包发送的推送通知。它仅限于POST请求,并且将免于跨站请求伪造(CSRF)保护。这样做将允许您使用Postman或任何其他RESTful服务测试视图。但是,在生产中,您应该删除此装饰器,以避免您的视图容易受到CSRF的影响。
要创建send_push
视图,首先添加以下导入以启用JSON响应并访问webpush
库中的send_user_notification
函数:
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET, require_POST
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
接下来,添加require_POST
装饰器,它将使用用户发送的请求主体来创建并触发推送通知:
@require_GET
def home(request):
...
@require_POST
@csrf_exempt
def send_push(request):
try:
body = request.body
data = json.loads(body)
if 'head' not in data or 'body' not in data or 'id' not in data:
return JsonResponse(status=400, data={"message": "Invalid data format"})
user_id = data['id']
user = get_object_or_404(User, pk=user_id)
payload = {'head': data['head'], 'body': data['body']}
send_user_notification(user=user, payload=payload, ttl=1000)
return JsonResponse(status=200, data={"message": "Web push successful"})
except TypeError:
return JsonResponse(status=500, data={"message": "An error occurred"})
我们在send_push
视图中使用了两个装饰器:require_POST
装饰器,它将视图限制为仅仅POST请求,以及csrf_exempt
装饰器,它将视图从CSRF保护中免除。
此视图需要POST数据并执行以下操作:它获取请求的body
内容,并使用json包将JSON文档反序列化为使用json.loads
的Python对象。json.loads
获取结构化JSON文档并将其转换为Python对象。
视图期望请求主体对象具有三个属性:
head
:推送通知的标题。body
:通知的正文。id
:id
请求用户的。
如果缺少任何必需的属性,视图将返回JSONResponse
并且呈现404“未找到”的状态。如果与给定的主密钥的用户存在,该视图将使用所述匹配的主键来返回user
,该主键使用来自django.shortcuts
库的get_object_or_404
函数。如果用户不存在,该函数将返回404错误。
该视图还使用了webpush
库中的send_user_notification
函数。该函数有三个参数:
User
:推送通知的收件人。payload
:通知信息,包括通知head
和body
。ttl
:用户脱机时应存储通知的最长时间(以秒为单位)。
如果没有错误发生,视图将返回JSONResponse
并且呈现200“成功”的状态和一个数据对象。如果KeyError
发生,则视图将返回500“内部服务器错误”状态。当对象的请求键不存在时发生KeyError
.
在下一步中,我们将创建相应的URL路由以匹配我们创建的视图。
第3步 - 将URL映射到视图
Django可以创建使用名为URLconf
的Python模块连接到视图的URL。此模块将URL路径表达式映射到Python函数(您的视图)。通常,在创建项目时会自动生成URL配置文件。在此步骤中,您将更新此文件以包含您在上一步中创建的视图的新路由以及django-webpush
应用程序的URL ,这将为订阅用户提供推送通知的端点。
开放urls.py
:
nano ~/djangopush/djangopush/urls.py
该文件将如下所示:
代码语言:javascript复制"""untitled URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
下一步是将您创建的视图映射到URL。首先,添加include
输入以确保将Django-Webpush库的所有路由添加到项目中:
"""webpushdjango URL Configuration
...
"""
from django.contrib import admin
from django.urls import path, include
接下来,导入您在上一步中创建的视图,并更新urlpatterns
列表以映射您的视图:
"""webpushdjango URL Configuration
...
"""
from django.contrib import admin
from django.urls import path, include
from .views import home, send_push
urlpatterns = [
path('admin/', admin.site.urls),
path('', home),
path('send_push', send_push),
path('webpush/', include('webpush.urls')),
]
此处,urlpatterns
列表会注册django-webpush
包的URL,并将您的视图映射到URL /send_push
和/home
。
让我们测试/home
视图以确保它按预期工作。确保您位于项目的根目录中:
cd ~/djangopush
运行以下命令启动服务器:
代码语言:javascript复制python manage.py runserver your_server_ip:8000
导航到http://your_server_ip:8000
。您应该看到以下主页:
此时,您可以使用该CTRL C
命令终止服务器,我们将继续创建模板并使用该render
功能在视图中呈现它们。
第4步 - 创建模板
Django的模板引擎允许您使用与HTML文件类似的模板定义应用程序的面向用户层。在此步骤中,您将为home
视图创建和呈现模板。
在项目的根目录中创建一个名为templates
的文件夹:
mkdir ~/djangopush/templates
如果此时在项目的根文件夹中运行ls
,输出将如下所示:
/djangopush
/templates
db.sqlite3
manage.py
/my_env
在templates
文件夹中创建一个名为home.html
的文件:
nano ~/djangopush/templates/home.html
将以下代码添加到文件中以创建一个表单,用户可以在其中输入信息以创建推送通知:
代码语言:javascript复制{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="vapid-key" content="{{ vapid_key }}">
{% if user.id %}
<meta name="user_id" content="{{ user.id }}">
{% endif %}
<title>Web Push</title>
<link href="https://fonts.googleapis.com/css?family=PT Sans:400,700" rel="stylesheet">
</head>
<body>
<div>
<form id="send-push__form">
<h3 class="header">Send a push notification</h3>
<p class="error"></p>
<input type="text" name="head" placeholder="Header: Your favorite airline