您的位置:首页 > 移动开发 > 微信开发

Django搭建微信公众平台详解 三

2015-12-07 23:21 603 查看
微信公众平台官方手册: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))


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息