微信公众平台官方手册:http://mp.weixin.qq.com/wiki/home/index.html
Python版本:2.7.10
Django版本:1.5
开发平台:新浪SAE
前提:了解django基本创建应用的步骤。根据微信公众平台官方手册一步步完成。
公众号:今天做了没
注释:千万别骂我,我就是刚学
上一节已经基本上完成了回复文本的功能,那么这一节,就用这个回复文本的功能,给公众号加上一些真实的功能。
增加功能:我收集了很多笑话、名人名言和小知识,我决定在用户发送“。”或者“.”,也就是当用户发送句号过来时,我就去随机取从笑话、名人名言或者小知识中取一条信息回复给用户。
1 。笑话、名人名言、小知识,分别储存在三张不同的表中,现在就需要在models.py中增加三个类。
from django.db import models class Joke(models.Model): content = models.TextField('笑话内容') class Knowledge(models.Model): content = models.TextField('知识内容') class Quote(models.Model): content = models.TextField('名人名言')
这里我就创建了三个类,使用:python manage.py syncdb,这样就可以在SAE中的mysql自动创建表了。自动创建的表名就是app名_类名,比如我这里是:wechat_joke、wechat_knowledge、wechat_quote。
然后,由于我要增加的内容都已经在excel里了,并且调整好了格式,所以我直接使用了导入。
下面是我在导入时的截图:
选择文件,选择好了,下面那个导入格式自动就变了,之后点执行,下面再看一下我的excel格式:
可以看到前面的id,这个是django在你没有设置主键的时候自动给加的,所以我在这里设置一下。并且下面的sheet名,要使用自己的表名。我这里第一行使用了行名,所以在导入的时候,有一个选项是忽略首行的选项,要选择上。这个导入就说这么多。
2. 下面就要在我们的视图views.py中增加功能了,第二节中我们是在post方法中增加的内容。现在还需要在post里面处理。
由于我使用了产生随机数的功能,所以需要:import random
import random #其它导入的就忽略了,跟第二节中的是一样的,只是增加了这个random from .models import Joke, Knowledge, Quote #这里还需要把我们的models.py中的模型导入 #下面继续完善我们的post, def post(self, request): str_xml = ET.fromstring(request.body) msgType = str_xml.findtext("MsgType") #这里将需要使用到的变量都使用类变量来存储 self.toUser = str_xml.findtext("FromUserName") self.fromUser = str_xml.findtext("ToUserName") self.content = str_xml.findtext("Content") self.nowtime = str(int(time.time())) #这里就是使用字典来完成在其它语言中的switch功能,我这里使用switch变量名,就是为了说明这件事, #这个名是随便起的。这样的话,我们就可以增加其它的字典映射关系,就可以处理不同的msgType消息了 switch = { 'text': self.onText } #我们的msgType暂时只有text,所以我们发送文本消息过来,就会调用onText()方法 return switch.get(msgType)(request) #onText专门来处理文本消息 def onText(self, request): #如果收到了句号,我们就从数据库中取消息回复 if self.content == "." or self.content == "。": #这里还是建立一个字典,为后面实例化不同的类做准备 switch = { 1: Joke, 2: Knowledge, 3: Quote } #由于我有三个表,要随机选择一个 select = random.randint(1, 3) #选择了表后,就计算表中有多少数据 total = switch[select].objects.count() #有了数据里后就可以随机选择一个了 num = random.randint(1, total) reply = switch[select].objects.get(id=num).content else: #如果收到的不是句号,那么我们就把用户的消息反转,发回去。 reply = self.content[::-1] t = loader.get_template('wechat/text.xml') c = Context({'toUser': self.toUser, 'fromUser': self.fromUser, 'nowtime': self.nowtime, 'content': reply}) return HttpResponse(t.render(c))
现在就可以实现我想要的功能了,在这里其实很容易发现,其实可以把这个类做成基类,把具体的方法通过继承来实现。不过我这里还不打算做,后面还有其它功能要增加,所以暂时先这样,等实在看不下去了再去处理。
views.py完整代码:有些和上面不一致的地方,因为我还要增加其它的功能
#coding:utf-8 from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from django.views.generic.base import View from django.template import loader, Context from xml.etree import ElementTree as ET import time import hashlib import random from .models import Joke, Knowledge, Quote class WeChat(View): @csrf_exempt def dispatch(self, *args, **kwargs): return super(WeChat, self).dispatch(*args, **kwargs) def get(self, request): 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 = 'bzzxhy1806znzqylhwhhxm265' # 2. 对发来的信息进入组合并sha1加密 hashlist = [token, timestamp, nonce] hashlist.sort() halstr = ''.join([s for s in hashlist]) halstr = hashlib.sha1(halstr).hexdigest() # 3. sha1加密的结果和发来的对比,相等就返回接收到的字符串 if halstr == signature: return HttpResponse(echostr) def post(self, request): str_xml = ET.fromstring(request.body) msgType = str_xml.findtext("MsgType") self.toUser = str_xml.findtext("FromUserName") self.fromUser = str_xml.findtext("ToUserName") self.content = str_xml.findtext("Content") self.nowtime = str(int(time.time())) switch = { 'text': self.onText } return switch.get(msgType)(request) def onText(self, request): #1. 判断用户信息是否已经记录,如果没有就插入到数据库中 #2. 判断当前用户是否为管理员,如果是进行管理员相当处理 if self.toUser == "": pass else: #3. 判断当前用户输入的文本: if self.content == "。" or self.content == ".": switch = { 1: Joke, 2: Knowledge, 3: Quote, } select = random.randint(1, 3) total = switch[select].objects.count() num = random.randint(1, total) reply = switch[select].objects.get(id=num).content elif self.content == "?" or self.content == "?": reply = "你问我?" else: reply = self.content[::-1] t = loader.get_template('wechat/text.xml') c = Context({'toUser': self.toUser, 'fromUser': self.fromUser, 'nowtime': self.nowtime, 'content': reply}) return HttpResponse(t.render(c))