FunctionGHW

立志成为真正程序员的码农,伪全栈,目前主要写C#

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

FunctionGHW posted @ 2014年3月11日 18:11 in 学习杂记 with tags Django Class-based view 微信公众平台 csrf_exempt , 2984 阅读

在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)
 
   ...
        

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

  • 无匹配
jaco 说:
2015年2月17日 16:20

你好,我最近在学习做微信开发平台,就在前面接入这卡住了post响应,能否留个联系方式让我请教一下?或者可以直接加我qq316921630,谢谢!


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter