启动Idiom/flask下的venv虚拟环境,运行python manage.py runserver命令启动Flask。然后打开微信开发者工具并扫码登录,选择flask/weapp-idiom小程序,加载完成后进入小程序登录页面,如图1所示。单击“微信登录”提示微信授权,如图2所示。单击“允许”按钮,即可进入到小程序首页。如图3所示。
单击“开始挑战”,进入答题页面,如图4所示。在答题页面,鼠标单击选项区的汉字,则会将该汉字填充到当前的答案框中。如要修改答案,可以单击答案中汉字,则该汉字退回到选项区。
如果填写4个汉字后,答案正确,则进入下一关,如图5所示。否则提示错误信息,如图6所示。
全部通关以后,提示通关信息如图7所示。单击“告诉朋友”按钮,即可分享好友,如图8所示。
单击“回到主页”,在主页点击“排行榜”即可查看比赛排行。如图9所示。
小程序因其“用完即走”的特性备用用户欢迎,其中各种答题类的小程序因具备一定的趣味性而异常火爆,下面,我们就模拟猜成语小程序,开发一款寓教于乐的“看图猜成语小程序”。
基本技能要求:
flask 基础知识
小程序基础知识
开发及运行环境:
虚拟环境:virtualenv。
数据库:PyMySQL驱动+ MySQL。
开发工具:微信开发者工具+PyCharm / Sublime Text 3。
PythonWeb 框架:Flask。
接口调试工具:Postman。
数据库设计:
本项目采用MySQL数据库,数据库名称为idiom。在小程序中涉及用户信息和题目信息,所以在idom数据库下包含2张数据表,数据表名称及作用如下:
user表:存储用户信息,包括用户昵称、头像和排名等。
exam表:存储题目信息,包括图片、答案和备选项等。
使用说明
使用pip安装virtualenv,命令如下:
pip install virtualenv
1
在“flask/”目录下,创建venv 虚拟环境,命令如下:
virtualenv venv
1
启动虚拟环境,
windows下命令如下:
venv\scripts\activate 1
mac下命令如下:
source venv\bin\activate
1
安装依赖,命令如下:
pip install -r requirements.txt 1
创建数据库,命名为idom
使用数据迁移命令
python manage.py db init python manage.py db migrate python manage.py db upgrade 1
3
创建完数据表后,将“flask\idiom.sql”文件导入到数据库
启动python,运行如下命令:
python manage.py runserver
1
开启小程序调试工具,新建项目,项目目录是“idiom/weapp-idiom”。
部分源码如下,其余完整详见下载。
from flask import Blueprint from app.models import Member,Exam from flask import jsonify,g,request from flask_httpauth import HTTPTokenAuth from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from app.libs.MemberService import MemberService from app import db from werkzeug.http import HTTP_STATUS_CODES api = Blueprint('api', __name__) # 设置Token验证 auth = HTTPTokenAuth(scheme='Bearer') serializer = Serializer('mrsoft', expires_in=1800) @auth.verify_token def verify_token(token): try: data = serializer.loads(token) # 验证token except: return False if 'user_id' in data: g.user_id = data['user_id'] return True return False @auth.error_handler def token_auth_error(): return error_response(401) def error_response(status_code, message=None): response = { "code": status_code, "msg": HTTP_STATUS_CODES.get(status_code), "data": {} } return jsonify(response) @api.route('/users/wx_login',methods=['POST']) def wx_login(): req = request.values # 接受数据 # 接受数据 nickname = req['nickname'] if 'nickname' in req else '' avatar = req['avatar'] if 'avatar' in req else '' # 判断code 是否存在 code = req['code'] if 'code' in req else '' if not code or len( code ) < 1: result = { "code": -1, "msg": "需要微信授权code", "data": {} } return jsonify(result) # 根据code,获取openid openid = MemberService.getWeChatOpenId( code ) if openid is None: result = { "code":-1, "msg":"调用微信出错", "data":{} } return jsonify(result) # 如果用户存在,写入member表中 member = Member.query.filter_by(openid=openid).first() if not member: member = Member( openid = openid, nickname = nickname, avatar = avatar, sesion = sesion, ) db.session.add(member) db.session.commit() sesionTotal = db.session.query(Exam).count() token = serializer.dumps({'user_id': member.id}) # 生成token # 返回结果 result = { "code":1, "msg":"登录成功", "data": {"userInfo": { "userId": member.id, "nickName": member.nickname, "avatar": member.avatar, "sesion": member.sesion, }, "sesionTotal":sesionTotal, "token": token.decode(), # byte 转化为string } } return jsonify(result) @api.route('/exams',methods=["POST"]) @auth.login_required def get_exam(): sesion = request.values['sesion'] try: exam = Exam.query.filter_by(id=sesion).first() result = { "code": 1, "data": { "answer": exam.answer, "candidates": exam.candidates.split(","), "image": exam.pictureUrl }, "message": "请求成功" } except: result = { "code": 0, "data": {}, "message": "请求失败" } return jsonify(result) @api.route('/exams/update_sesion',methods=["POST"]) @auth.login_required def update(): sesion = int(request.values['sesion']) userId = int(request.values['userId']) # 更改用户关卡 try: member = Member.query.filter_by(id=userId).first() member.sesion = sesion db.session.commit() result = { "code": 1, "msg": "请求成功", "data": { "sesion": sesion } } except: result = { "code": 0, "msg": "更新失败", "data": {} } return jsonify(result) @api.route('/rank',methods=["POST"]) @auth.login_required def get_rank(): ''' 排行榜 ''' members = Member.query.order_by(Member.sesion.desc()).limit(10).all() data = [] for item in members: userInfo = { "userId": item.id, "nickname": item.nickname, "avatar": item.avatar, "sesion": item.sesion, } data.append(userInfo) # 返回结果 result = { "code":1, "msg":"请求成功", "data": data } return jsonify(result)