PythonTip >> 博文 >> Django python

Django接入微信公众平台post无响应问题的解决过程

zihua 2014-03-12 15:03:35 点击: 1240 | 收藏


在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 了, 悲剧的发现还是不行<T_T>。是否是因为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)
 
   ...

到这里,算是真正的接入成功了

原文链接:http://www.tuicool.com/articles/aAbEFf

作者:zihua | 分类: Django python | 标签: django python | 阅读: 1240 | 发布于: 2014-03-12 15时 |