1、flask中提供了一些特殊的变量和方法,在不进行传递的情况下就可以在模板中直接使用
常见的变量和方法有:
(1) request: 封装的是请求相关的参数
(2)session: 存储用户相关的数据
(3)config: 封装了app中的配置信息
(4)url_for( ): 反解析方法,通过函数找到路径
(5)get_flashed_messages( ): 消息队列方法,一旦调用会获取flash中封装的字符串数据,用到了session进行存储, 所以需要设置SECRET_KEY
代码:
from flask import Flask, render_template, session, flash
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kun'
@app.route('/')
def work1():
session['name'] = 'gaohan'
return render_template('file01.html')
@app.route('/index<int:id>')
def index(id):
flash(u'人生苦短')
flash(u'我用python')
return 'hello'
if __name__ == '__main__':app.run(debug=True)
模板(file01.html)中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h2>request对象: {{ request.url }}</h2>
<h2>session对象: {{ session.name }}</h2>
<h2>config对象: {{ config.SECRET_KEY }}</h2>
<h2>url_for方法: {{ url_for('index',id=10) }}</h2>
{% for i in get_flashed_messages() %}
{{ i }}
{% endfor %}
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</body>
</html>
2、传统form表单
传统form: 通过标签,表单域,提交按钮等组成,如果一旦标签写好了,更改麻烦,校验需要自己写逻辑判断
代码:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def work1():
return render_template('file02.html')
@app.route('/register', methods=['POST'])
def register():
dict_data = request.form
username = dict_data.get('user')
password = dict_data.get('password')
repassword = dict_data.get('repassword')
if not all([username, password, repassword]):return '参数不完整'
if password != repassword:return '密码输入不一样'
return '注册成功'if __name__ == '__main__':
app.run(debug=True)
模板(file02.html)中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/register" method="post">
<input type="text" name="user" placeholder="请输入用户名">
<input type="text" name="password" placeholder="请输入密码">
<input type="text" name="repassword" placeholder="请再次输入密码">
<input type="submit" value="提交">
</form>
</body>
</html>
3、flask_WTF表单
flask_WTF表单: 通过字段的方式显示界面,通过函数验证表单中的值
好处: 维护更加方便, 提供csrf验证
使用流程:
(1)属于flask中的扩展包,需要安装
(2)定义类,继承自FlaskForm
(3)在类中编写字段,编写函数验证字段
(4)创建表单类,渲染到页面中
注意点:
(1)wtform表单提供了csrf验证机制
(2)csrf_token的生成依赖SECRET_KEY
(3)通过validate_on_submit验证字段中的验证信息,会对'POST', 'PUT', 'PATCH', 'DELETE'提交方式校验
(4)获取表单中内容的方法: form.字段.data
代码:
from flask import Flask,render_template
from flask.ext.wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kun'
class Myform(FlaskForm):
username = StringField(u'用户名', validators=[DataRequired()])
password = PasswordField(u'密码', validators=[DataRequired()])
repassword = PasswordField(u'再次确认密码', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField(u'提交')
@app.route('/')
def work1():
form = Myform()
return render_template('file03.html', form=form)
@app.route('/register', methods=['POST'])
def register():
form = Myform()
if form.validate_on_submit():username = form.username.data
password = form.password.data
repassword = form.repassword.data
print username
print password
print repassword
return '注册成功'
return '注册失败'
if __name__ == '__main__':
app.run(debug=True)
模板(file03.html)中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/register" method="post">
{{ form.csrf_token }}
{{ form.username.label }}
{{ form.username }}
{{ form.password.label }}
{{ form.password }}
{{ form.repassword.label }}
{{ form.repassword }}
{{ form.submit }}
</form>
</body>
</html>
4、flask创建数据库表格
要想操作数据库,就要安装flask_sqlalchemy,它是用来操作数据库的扩展包
使用流程:
(1) 安装扩展包2个
(2)导入flask_sqlalchemy中的SQLALCHEMY类
(3)创建SQLAlchemy对象,关联app
(4)编写自定义类,继承db.Model
(5)操作,比如:创建表,删除表,添加数据...注意点:
1.如果不指定数据库中表的名字,默认是类名的小写
2.如果需要自定义名字,编写__tablename__
代码:(注意要先创建数据库flaskdb1)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/flaskdb1'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Role(db.Model):
__tablename__ ='roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return 'Role:%s' % self.name
class User(db.Model):
__tablename__ ='users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
role_id = db.Column(db.ForeignKey(Role.id))
def __repr__(self):
return 'User:%s' % self.name
@app.route('/work1')
def work1():
return 'helloworld'
if __name__ == '__main__':
db.drop_all()
db.create_all()
app.run(debug=True)
5、flask中查询数据库
需求1:如果知道用户(user)的情况下,能不能直接查询到该用户所扮演的角色(role)
user.role
需求2:如果知道角色(role)的情况下,能不能直接查询到该角色由哪些用户所扮演(users)
role.users
解决方法: 通过backref反向引用既可以,方便查询, 添加在一方,两个表之间需要有外键关系.
代码:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@localhost:3306/flaskdb1'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
user = db.relationship('User',backref='role',lazy = 'dynamic')
def __repr__(self):
return 'Role:%s'% self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
email = db.Column(db.String(128))
password = db.Column(db.String(128))
role_id = db.Column(db.ForeignKey(Role.id))
def __repr__(self):
return 'User:%s,%s,%s,%s'% self.name,self.email,self.password,self.role_id
@app.route('/')
def index():
return 'helloworld'
if __name__ == '__main__':
db.drop_all()
db.create_all()
# 添加数据
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
# 再次插入一条数据
ro2 = Role(name='user')
db.session.add(ro2)
db.session.commit()
us1 = User(name='wang', email='wang@163.com', password='123456', role_id=ro1.id)
us2 = User(name='zhang', email='zhang@189.com', password='201512', role_id=ro2.id)
us3 = User(name='chen', email='chen@126.com', password='987654', role_id=ro2.id)
us4 = User(name='zhou', email='zhou@163.com', password='456789', role_id=ro1.id)
us5 = User(name='tang', email='tang@itheima.com', password='158104', role_id=ro2.id)
us6 = User(name='wu', email='wu@gmail.com', password='5623514', role_id=ro2.id)
us7 = User(name='qian', email='qian@gmail.com', password='1543567', role_id=ro1.id)
us8 = User(name='liu', email='liu@itheima.com', password='867322', role_id=ro1.id)
us9 = User(name='li', email='li@163.com', password='4526342', role_id=ro2.id)
us10 = User(name='sun', email='sun@163.com', password='235523', role_id=ro2.id)
db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
db.session.commit()
app.run(debug=True)
6、图书馆管理小项目
功能描述:
(1)可以添加书籍,作者
(2)展示作者,书籍
(4)添加作者的时候,作者名存在,书名也存在不能添加
(5)添加作者的时候,作者不存在,可以添加流程:
(1)配置数据库
(2)配置表单
(3)渲染表单
(4)展示数据
(5)操作表单,数据
代码:
from flask import Flask,flash,redirect,render_template
from flask import request
from flask.ext.wtf import FlaskForm
from flask_sqlalchemy import SQLAlchemy
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired
app = Flask(__name__)
#数据库配置信息
class Config(object):
SECRET_KEY = 'kun'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@localhost:3306/flaskdb2'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config.from_object(Config)
db = SQLAlchemy(app)
# 编写模型类
# 一个作者可以写多本书
class Author(db.Model):
__tablename__ = 'authors'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
books = db.relationship('Book', backref='author', lazy ='dynamic')
# 一本书只有一个作者
class Book(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64))
author_id = db.Column(db.ForeignKey(Author.id))
# 定义表单类
class BookForm(FlaskForm):
bookname = StringField(label=u'书名',validators=[DataRequired()],render_kw={'placeholder':u'请输入用户名'})
authorname = StringField(u'作者',validators=[DataRequired()],render_kw={'placeholder':u'请输入作者'})
submit = SubmitField(u'提交')
# 展示书籍
@app.route('/')
def index():
# 1.创建表单
form = BookForm()
# 2.查询数据
authors = Author.query.all()
# 3.将数据渲染到页面
return render_template('file04.html', form=form, authors=authors)
# 添加书籍
@app.route('/add_book',methods=['POST'])
def add_book():
# 1.创建表单
form = BookForm()
# 2.校验表单
if form.validate_on_submit():
# 获取到参数,作者名,书名
authorname = form.authorname.data
bookname = form.bookname.data
author = Author.query.filter(Author.name == authorname).first()
# 判断
if author:
# 查询该作者底下,是否有该书名
book = Book.query.filter(Book.name == bookname,Book.author_id == author.id).first()
# 该书存在
if book:
flash(u'该作者已经添加该书啦')
else:
# 创建作者,和书,添加到数据库
author = Author(name = authorname)
db.session.add(author)
db.session.commit()
book = Book(name = bookname)
db.session.add(book)
db.session.commit()
# 3.响应
return redirect("/")
#删除书籍方法一
#@app.route('/delete_book/<int:id>')
#def delete_book(id):
# #1.根据编号获取到书籍
# book = Book.query.get(id)
# #2.删除,提交
# db.session.delete(book)
# db.session.commit()
# #3.重定向到展示页面
# return redirect("/")
@app.route('/delete_book/<int:id>')
def delete_book(id):
book = Book.query.get(id)
db.session.delete(book)
db.session.commit()
return redirect('/')
#删除作者和作者所有关联的书籍
@app.route('/delete_author')
def delete_author():
id = request.args.get('id')
# 1.通过编号获取到作者对象author = Author.query.get(id)
# 2.获取到作者,所有的书籍books = author.books
# 3.删除书籍, 作者,提交for book in books:
db.session.delete(book)
db.session.delete(author)
db.session.commit()
return redirect('/')if __name__ == '__main__':
# 为了演示方便,先删除所有的表
db.drop_all()
# 创建所有表
db.create_all()
# 添加测试数据
# 生成数据
au1 = Author(name='老王')
au2 = Author(name='老尹')
au3 = Author(name='老刘')
# 把数据提交给用户会话
db.session.add_all([au1, au2, au3])
db.session.commit()
# 提交会话
bk1 = Book(name='老王回忆录', author_id=au1.id)
bk2 = Book(name='我读书少,你别骗我', author_id=au1.id)
bk3 = Book(name='如何才能让自己更骚', author_id=au2.id)
bk4 = Book(name='怎样征服美丽少女', author_id=au3.id)
bk5 = Book(name='如何征服英俊少男', author_id=au3.id)
# 把数据提交给用户会话
db.session.add_all([bk1, bk2, bk3, bk4, bk5])
# 提交会话
db.session.commit()
app.run(debug=True)
模板(file04.html)中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/add_book" method="post">
{{ form.csrf_token }}
{{ form.bookname.label }}
{{ form.bookname }}
{{ form.authorname.label }}
{{ form.authorname }}
{{ form.submit }}
{% for message in get_flashed_messages() %}
<h4>{{ message }}</h4>
{% endfor %}
</form><form action="">
{% for author in authors %}
<li>
{{ author.name }} <a href="{{ url_for('delete_author',id = author.id) }}">删除</a>
</li>
<li>
{% for book in author.books %}
<li>
{{ book.name }} <a href="{{ url_for('delete_book',id = book.id) }}">删除</a>
</li>
{% endfor %}
</li>
{% endfor %}
</form>
</body>