django+sae微信开发-简单的鹦鹉学舌功能

网上已经有一些优秀的教程了,但是大多数基于web.py,最近学了点django,就用django写个简单的demo。


准备工作

基础的python知识,基础的django框架知识。
申请sae,申请微信公众平台。看一下sae和微信平台开发文档。
可以参考以下几个教程有个大致的了解:(包括申请sae,微信平台,url设置等步骤)
使用python一步一步搭建微信公众平台(一)
利用SAE搭建微信公众平台(二)微信的验证和自动回复
微信机器人:小蜗牛有道翻译小助手——Django + SAE + 微信公众帐号自动回复开放接口


建立项目及配置

建立项目:django-admin.py startproject mysite
按照sae要求更名为版本1:mv mysite 1
编写配置文件:config.yaml

1
2
3
4
5
6
libraries:
- name: "django"
version: "1.4"
- name: lxml
version: "2.3.4"

编写index.wsgi:

1
2
3
4
import sae
from mysite import wsgi
application = sae.create_wsgi_app(wsgi.application)

这时候文件夹1下应该有4个文件(夹):
config.yaml index.wsgi manage.py mysite
切换到mysite文件夹下,建立一个templates文件夹:
cd mysite; mkdir templates
修改settings.py:

1
2
3
4
5
6
TIME_ZONE = 'Asia/Shanghai'
LANGUAGE_CODE = 'zh-cn'
# 添加模板文件夹
TEMPLATE_DIRS = (
'./mysite/templates',
)

编写views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# -*- coding: utf-8 -*-
from django.http import HttpResponse
import hashlib
import time
import os
import urllib2,json
from lxml import etree
from django.views.generic.base import View
from django.shortcuts import render
class WeixinInterfaceView(View):
def get(self, request):
#得到GET内容
signature = request.GET.get('signature', None)
timestamp = request.GET.get('timestamp', None)
nonce = request.GET.get('nonce', None)
echostr = request.GET.get('echostr', None)
#自己的token
token = 'yourtoken' #这里改写你在微信公众平台里输入的token
#字典序排序
tmpList = [token, timestamp, nonce]
tmpList.sort()
tmpstr = '%s%s%s' % tuple(tmpList)
#sha1加密算法
tmpstr = hashlib.sha1(tmpstr).hexdigest()
#如果是来自微信的请求,则回复echostr
if tmpstr == signature:
return render(request, 'get.html', {'str': echostr},
content_type='text/plain')
def post(self, request):
str_xml = request.body.decode('utf-8') #use body to get raw data
xml = etree.fromstring(str_xml) #进行XML解析
toUserName = xml.find('ToUserName').text
fromUserName = xml.find('FromUserName').text
createTime = xml.find('CreateTime').text
msgType = xml.find('MsgType').text
content = xml.find('Content').text #获得用户所输入的内容
msgId = xml.find('MsgId').text
return render(request, 'reply_text.xml',
{'toUserName': fromUserName,
'fromUserName': toUserName,
'createTime': time.time(),
'msgType': msgType,
'content': content,
},
content_type = 'application/xml'
)

在这里使用了视图类,实现了get和post方法来处理这两种请求。get方法用来验证,验证方法在微信开发文档里有描述。post方法实现消息回复,xml解析得到相应内容,xml内容详见微信开发文档,需要严格按照格式回复。


编写templates:

进入mysite里的templates文件夹,建立两个模版文件get.html和reply_text.xml:
get.html内容很简单,直接定义一个变量str就可以:{{ str }}

在views.py的get方法里,
return render(request, 'get.html', {'str': echostr}, content_type='text/plain')
render后str会被替换成echostr返回。

reply_text.xml:

在这个xml模版里定义了一些变量,然后我们在post方法里使用这个模板,实际上也就是文档里定义的xml文件,把需要替换的地方用自己定义的变量替换。然后在render方法里,把变量替换为需要的信息,我们把’content’: content直接用content返回,就可以直接回复收到的内容。

1
2
3
4
5
6
7
8
9
return render(request, 'reply_text.xml',
{'toUserName': fromUserName,
'fromUserName': toUserName,
'createTime': time.time(),
'msgType': msgType,
'content': content,
},
content_type = 'application/xml'
)

编写urls.py

1
2
3
4
5
6
7
from django.conf.urls import patterns, include, url
from mysite.views import WeixinInterfaceView
from django.views.decorators.csrf import csrf_exempt #remove csrf
urlpatterns = patterns('',
url(r'^weixin/', csrf_exempt(WeixinInterfaceView.as_view())),
)

在这里用csrf_exempt方法去除csrf验证。

本机测试

一开始不清怎么调试,官方给的调试也很鸡肋,只能返回出错结果,看不到具体信息。后来想到了用curl这个命令发送post请求(也可以用python模拟发送post请求)
curl -X POST -d @post.xml http://127.0.0.1:8000/weixin/ > result.html
curl的用法可以自行搜索,post.xml就是我们要发送的xml文件,格式参考微信开发文档。把结果重定向到一个result.html文件里边,用浏览器打开就可以查看是什么错误了。
如果使用python发送post请求可以安装requests模块:
sudo pip install requests

然后用python代码发送post请求,查看返回结果:

1
2
3
4
5
6
7
8
9
import requests
import codecs
f = codecs.open(u'post.xml', u'r', u'utf-8')
content = u''.join(f.readlines())
f.close()
res = requests.post(u'http://2.pegasuswang.sinaapp.com/wechat/', data=content.encode(u'utf-8'))
print res.text

部署

可以使用svn直接commit到sae上即可。

演示效果