在SAE上使用Python进行微信公众平台开发,因为SAE支持Django框架,就试着把原先基于web.py的代码换成基于Django的(使用SAE提供的Django v1.4),并使用了Django v1.3才新加的基于类的视图(Class-based view)。View类同样有get和post方法,所以代码做的改动不多。
# coding: utf-8
from django.http import HttpResponse
from django.template import loader, Context
from django.views.generic.base import View
from lxml import etree
import hashlib, time
class WeixinView(View):
def __init__(self):
pass
def get(self, request):
#获取GET参数
data = request.GET
signature = data.get('signature')
timestamp = data.get('timestamp')
nonce = data.get('nonce')
echostr = data.get('echostr')
ret = ''
#如果是来自微信的请求,则回复echostr
if self.__validate_wx(signature, timestamp, nonce, echostr):
ret = echostr
return HttpResponse(ret)
def post(self, request):
#获得post来的数据 raw string,不能使用request.POST
str_xml = request.body
xml = etree.fromstring(str_xml)
content = xml.find("Content").text
msgType = xml.find("MsgType").text
fromUser = xml.find("FromUserName").text
toUser = xml.find("ToUserName").text
...
#微信公众平台请求 验证方法
def __validate_wx(self, signature, timestamp, nonce, echostr):
# do validate
...
上传代码后成功接入,正确返回echostr。
一切似乎都正常,然而使用手机端微信进行测试时却收不到任何回应。 几番测试,我发现post方法没有被调用。Google一下,最后找到 这个帖子
。 看来问题出在CSRF保护机制上。
即使在get和post方法上都加上 @csrf_exempt
了, 悲剧的发现还是不行。是否是因为Class-based view的原因?改成基于函数的view后,果然成功了。 不过我还是想用基于类的视图来处理请求。在Class-based view里是不是需要使用其他的装饰器替换? 搜索答案的时候跑进stackoverflow了,看 这里
。 看来我还是对基于类的视图这东西不甚了解,查看Django官方文档发现:无论请求是get还是post, 都是先由View类的dispatch方法处理,之后根据请求的method再调用get或post方法。根据这个人的回答,感觉有道理, 于是重写dispatch方法:
# coding: utf-8
...
from django.views.decorators.csrf import csrf_exempt
class WeixinView(View):
...
@csrf_exempt #override
def dispatch(self, *args, **kwargs):
return super(WeixinView, self).dispatch(*args, **kwargs)
...
到这里,算是真正的接入成功了