这篇文章介绍如何通过Django框架搭建一个后台,实现接口编写、实时通讯以及推送功能。
我使用的工具:
PyCharm 用于编写代码,破解方法在这里,如果不行请自行找其他方式破解
Postman 用于测试接口
mysql 服务器数据库操作我选用的是mysql,不过本文不打算讲数据库的东西,可以不装
学习过程中参考链接:
廖雪峰Python教程,学习Python的基本使用
菜鸟教程,学习环境的搭建和使用,本文主要内容
建议安装好我上面提到的工具,还有上面菜鸟教程的内容和本文编写接口功能基本类似,可以直接参考该链接。还有Django是需要先安装的,我是通过pip3 install django进行安装的,安装详细教程也可以参考菜鸟教程上。
开始
首先新建一个项目,打开终端cd到一个目录下,执行语句既可创建一个Django项目,helloworld表示项目文件名,可自定义
$ cd desktop
$ django-admin.py startproject helloworld
![](https://img.haomeiwen.com/i2121010/e94c7e47adc54598.png)
目录说明:
- hellowrold:项目容器
- manage.py:命令行工具,可以让你通过命令行与该Django交互。比如数据库操作
- hellowrold/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。不常使用但是是必须的
- hellowrold/settings.py: 该 Django 项目的设置/配置。经常使用
- hellowrold/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。可以看做是后台api接口
- hellowrold/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。没用过
新建一个app
cd这个项目,创建一个app,app名为example,表示该项目的一个分支
python manage.py startapp example
然后在setting文件的INSTALLED_APPS里添加 'example'
![](https://img.haomeiwen.com/i2121010/acffa2df0f3fa614.png)
启动服务器
1.用pycharm打开该项目,右上角-file-open,此时在pycharm上运行(run)成功。
2.或者在终端(teminal) cd 到该helloworld文件路径,通过输入命令来启动服务器,这个路径要注意不要弄错,要确定是manage.py文件的目录
$ cd 路径/hellowrold
$ python manage.py runserver 0.0.0.0:8000 //8000指的是端口号,不说明的情况下为8000,也可以自行修改
这样就启动了服务器,打开浏览器输入127.0.0.1:8000即可看到It worked!,说明服务器启动成功。
让周围设备也能进入到本机的服务器
通过pycharm运行启动的服务器,只能在本机上查看到,即在浏览器上输入127.0.0.1:8000,而同一网络下的手机或电脑都无法查看,要让周围设备也能进入,必须使用终端(terminal)的方式启动服务器,terminal除了上面的方法外,在pycharm内也有一个Terminal选项,在那里执行命令也可以。
![](https://img.haomeiwen.com/i2121010/a31124791120a25f.png)
然后还有关键的一点,在项目中找到setting.py,在里面的'ALLOWED_HOSTS = []'中添加本机的IP地址,如
ALLOWED_HOSTS = ['127.0.0.1',
'192.168.0.1']
本机IP地址在系统偏好设置-网络中看到。
现在,只要和本机在同一网络下的设备,都可以通过浏览器进入到我们的服务器中了。
尝试写一个接口
打开example目录下views.py文件,填写内容
from django.http import HttpResponse,JsonResponse
def hello(request):
return HttpResponse('hello world') //返回普通文本数据
# return JsonResponse({'data':'response'}) //返回json格式数据
上面代码应该好理解,在执行hello函数的时候返回一段内容,其中如果需要返回json格式的内容,需要导入JsonResponse
然后在urls.py中添加
from django.conf.urls import url
from django.contrib import admin
import example.views as views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^helloworld/hello', views.hello),
]
import example.views as views 导入example的views文件,以views来命名
url(r'^helloworld/hello', views.hello) 新建一个接口为hello/hello的API,此时访问127.0.0.1:8000/helloworld/hello即可看到返回值
写一个get接口
然后就可以些多几个接口进行测试,现在尝试写一个get请求的接口,同样是在view文件里编写接口函数,然后在urls文件中定义接口路径
def get_test(request):
if request.method == 'GET':
return HttpResponse('接收到get请求')
return HttpResponse('error')
urls.py文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^helloworld/hello', views.hello),
url(r'^helloworld/get_test', views.get_test),
]
注意,urls.py中定义好接口路径,可能不会马上生效,如果发现接口无效,可以尝试重新开启服务器。
写一个post接口
位置还是一样
def post_test(request):
if request.method == 'POST':
title = request.POST.get('title','值为空时')
return HttpResponse('接收到post请求,接收到值: ' + title)
return HttpResponse('error')
url(r'^helloworld/post_test', views.post_test),
还记得上面提到的postman工具吗,我们在浏览器是没有办法测试post接口的,打开postman输入链接和带参,点击send即可发送post请求
![](https://img.haomeiwen.com/i2121010/0bcc17e7e639b492.png)
如果post不成功,一是csrf错误,请参考该链接,解决办法是在setting.py文件里注释掉 MIDDLEWARE的'django.middleware.csrf.CsrfViewMiddleware'即可
尝试写一个聊天室
服务器有了,接口也会了,现在就要学习如何搭建一个聊天室进行聊天。聊天室的实现我是在该简书链接中学习的。
在setting的INSTALLED_APPS下添加'channels'。
如果是初次使用pycharm,可能会没有一些库,如channels等,这样在导入库的试试会出错,可以在Prederences-Project:helloworld-Project Interpreter中添加必须的库即可导入。
接着继续在setting中添加
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgiref.inmemory.ChannelLayer",
'ROUTING': 'helloworld.routing.channel_routing',
},
}
这样就配置好了通讯的通道
在example目录下新建consumers.py文件,内容为
from channels import Group
import json
from channels import channel_layers
def ws_connect(message):
print('已连接客户端')
Group('users').add(message.reply_channel)
message.reply_channel.send({
'text': json.dumps({
'msg': u"你好,很高兴为你服务。",
'talk': False
})
})
def ws_disconnect(message):
print('与客户端断开连接')
Group('users').discard(message.reply_channel)
def ws_receive(message):
print('接收到客户端发来的消息')
data = json.loads(message['text'])
message.reply_channel.send({
'text': json.dumps({
'msg': u"我正在思考你的问题{%s}" % data["text"],
'talk': True
})
})
这里是channels通讯的三个函数,连接客户端、断开客户端以及收到客户端发送的消息。
接着做一个HTML页面用于测试,在example目录下新建templates文件,在里面继续新建一个example的文件,在里面新建一个chat.html,内容如下
![](https://img.haomeiwen.com/i2121010/9ca6aa5ad0f158e0.png)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Django Channels</title>
</head>
<body>
<div style="text-align: center;margin-top: 50px">
<input id="message" type="text" style="width: 300px" placeholder="输入消息">
<button id="send-message" style="width:80px;margin-left:20px;">发送</button>
</div>
<table id="show-message" style="width: 410px;margin: 0 auto;margin-top: 10px">
<tr>
<td style="text-align: center; border-bottom:1px dashed #000;"><strong>聊天记录</strong></td>
</tr>
</table>
</body>
<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var socket = new WebSocket('ws://' + window.location.host + '/users/');
if (socket.readyState == WebSocket.OPEN) {
socket.onopen();
}
socket.onmessage = function (message) {
var data = JSON.parse(message.data);
updateLog("机器人", data["msg"]);
$("#message").val("");
$("#message").focus();
};
$("#send-message").click(function () {
var inputText = $("#message").val();
if (typeof(inputText) == "undefined" || inputText.length < 1) {
alert("没有输入信息");
}
else {
var msg = {"text": inputText};
socket.send(JSON.stringify(msg));
updateLog("你", inputText);
}
});
function updateLog(name, message) {
var chat = $("#show-message");
var ele = "<tr><td>" + name + ": " + message + "</td></tr>"
chat.append(ele);
}
</script>
</html>
在views中添加
def chat_page(request):
return render(request, 'example/chat.html')
在urls中添加
url(r'^helloworld/chat_page', views.chat_page),
此时浏览器打开链接127.0.0.1:8000/helloworld/chat_page即可看到显示页面,尝试输入一些值
![](https://img.haomeiwen.com/i2121010/798c725a3b3cb5c6.png)
完成聊天室
由此就完成了聊天室的功能,现在解释一下刚刚的操作,我们在setting.py的INSTALLED_APPS中添加了channels,并且添加了CHANNEL_LAYERS配置通道路径,就是routing.py,routing里导入了consumers.py,我们在consumers里面就可以进行通讯的操作了,在views里我们添加了chat_page函数,该函数的作用是回调一个网页供浏览器展示。
在chat.html里有个路径,var socket = new WebSocket('ws://' + window.location.host + '/users/');因为channels是使用websocket进行通讯的,所以路径头为ws://,后面接的/users/可以修改,用于判断处理不同用户连接服务器,比如user1,那么在连接服务器的时候就会在consumers.ws_connect函数中获取到user1。
用户通讯目前的功能只是一个聊天室,且机器人的回复是message.reply_channel.send(),就是顺着该通道返回,这样并不能做到多人通讯。记得在ws_connect里的Group('users').add(message.reply_channel)吗,这里表示Group的名为'users'的组添加了该客户端的通道,可以看到在断开连接时ws_disconnect该组进行了对应通道的删除,我们可以通过这个功能进行双人通讯或群组通讯,只要根据上面的user1的方式进行匹配即可。
服务器进行iOS推送
所谓推送,可以是客户端正处于和服务器端的连接过程中,服务器通过建立的通讯管道进行消息推送,也可以是像微信那样,即便手机app被手动刷掉了,也能有一个消息弹窗,这里就说一下这种推送。
iOS有本地推送和网络推送,关于网络推送我之前有讲过,链接在这里,建议先看一下这篇文章,因为我们需要用到里面的推送证书,获取到证书之后还需要处理成pem格式,证书的获取和处理可以参考这篇文章
证书处理
从钥匙串中将推送证书导出来后为.p12文件,通过终端将其转换为pem格式,现将该p12文件放到桌面上,假设该.p12文件名为mycert.p12
$ cd desktop
$ openssl pkcs12 -in mycert.p12 -out MyApnsCert.pem -nodes
现在能在桌面上获取到MyApnsCert.pem文件,将该文件拖入到example目录下,这样证书处理就完成了
添加推送函数
还是在views.py上进行
首先需要导入一个库,如果没有就按我上面说的进行添加,这个库的github地址
from apns2.client import APNsClient
from apns2.payload import Payload
def push_ios(request):
token_hex = 'device token'
payload = Payload(alert="Hello World!", sound="default", badge=1)
topic = 'your bundle identifier'
client = APNsClient('example/MyApnsCert.pem', use_sandbox=True, use_alternative_port=False)
client.send_notification(token_hex, payload, topic)
return HttpResponse('response')
device token不用我说了吧,知道网络推送的就知道怎么获取,这个值一般是在客户端连接上服务器之后发送给服务器,以供服务器进行推送用,服务器存储这一块本文就不说了。
payload里面带的是内容,以json的格式发送,上面的数值在iOS设备上收到的内容格式为
aps = {
alert = "Hello World!";
badge = 1;
sound = default;
};
topic 为iOS app的bundle id
client创建时注意路径问题,如果路径不对是会报错的,参数use_sandbox指开发模式,该token是生产模式时则改成false
然后写好接口即可。
url(r'^helloworld/push_ios', views.push_ios),
调用后很快就能看到手机收到推送证书了。
结语
本文介绍了如何通过Django框架搭建一个后台,并且实现了聊天功能,支持双人聊天、群聊,以及对iOS设备的消息推送功能,每一个功能都花了我好多时间,写这篇文章可以帮助我梳理知识点,应该也能帮到需要的人。
网友评论