Demo体验:猜数字 – Flask
难度:1
使用扩展:Flask-Bootstrap、Flask-WTF
本文首发于知乎专栏:Hello, Flask!
– – – – –
每个学编程的人大概都写过猜数字游戏,今天我们用Flask来做一个Web版本的猜数字。功能很简单,只有两个路由,三个模板和一个表单组成。扩展的版本见项目的Github页面(页尾)。
项目结构
|-GuesstheNumber 项目名称
|-guess.py
|-templates/ 模板文件夹
|-index.html
|-guess.html
|-base.html 基模板
|-venv/ 虚拟环境
实现代码
guess.py
# -*- coding: utf-8 -*-
import random
from flask import Flask, render_template, flash, redirect, url_for, session
from flask_wtf import Form
from wtforms import IntegerField, SubmitField
from wtforms.validators import Required, NumberRange
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.config['SECRET_KEY'] = 'very hard to guess string' #设置secret key
bootstrap = Bootstrap(app) # 初始化Flask-Bootstap扩展
@app.route('/')
def index():
# 生成一个0~1000的随机数,存储到session变量里。
session['number'] = random.randint(0, 1000)
session['times'] = 10
return render_template('index.html')
@app.route('/guess', methods=['GET', 'POST'])
def guess():
times = session['times'] # 从session变量里获取次数
# 从session变量里获取在index函数里生成的随机数字
result = session.get('number')
form = GuessNumberForm()
if form.validate_on_submit():
session['times'] = times # 更新次数值
if times == 0:
flash(u'你输啦……o(>﹏<)o')
return redirect(url_for('.index'))
answer = form.number.data
if answer > result:
flash(u'太大了!你还剩下%s次机会' % times)
elif answer < result:
flash(u'太小了!你还剩下%s次机会' % times)
else:
flash(u'啊哈,你赢了!V(^-^)V')
return redirect(url_for('.index'))
return render_template('guess.html', form=form)
class GuessNumberForm(Form):
number = IntegerField(u'输入数字(0~1000):', validators=[
# 传入验证函数和相应的错误提示信息。
Required(u'输入一个有效的数字!'),
NumberRange(0, 1000, u'请输入0~1000以内的数字!')])
submit = SubmitField(u'提交')
if __name__ == '__main__': # 用于heroku部署,本地可省略
app.run()
index.html
{% extends "base.html" %}
{% block page_content %}
<!-- 传入url_for的参数是视图函数的名称 -->
<a class="btn btn-success btn-lg" href="{{ url_for('guess') }}">开始游戏</a>
{% endblock %}
guess.html
{% extends "base.html" %} <!-- 引入基模板 -->
{% import "bootstrap/wtf.html" as wtf %}
{% block page_content %}
<!-- 使用Flask-Bootstrap提供的函数来生成默认样式的表单 -->
{{ wtf.quick_form(form) }}
{% endblock %}
完整的项目见源码(底部)。
相关知识
- session(会话)
session是Flask的上下文(context)全局变量,可以用来存储(用字典的形式)请求之间需要“记住”的值。在这个猜数字游戏里,我使用它来存储生成的随机数和剩余的机会次数。
要使用session,得先设置一个secret key,这用来给Cookie签名以加密session,这样做的效果是用户可以看到cookie但不能篡改它。尽管如此,session并不是安全的,不能用来存储密码,这个视频演示了一个破解session的过程:https://youtu.be/mhcnBTDLxCI。
更多细节见:http://flask.pocoo.org/docs/0.11/quickstart/#sessions
安装和运行
源码地址:https://github.com/helloflask/guess-flask
下载或使用git命令克隆项目后,切换到程序根目录。使用virtualenv创建一个虚拟环境,激活后使用pip安装所需依赖:
pip install -r requirements.txt
然后运行:
set FLASK_APP=guess.py
flask run