Flask学习笔记(基础)
Flask运行原理(源码解读)
https://blog.csdn.net/sinat_36651044/article/details/77532510
1、最简单的开始
|-fflask |-static |-templates |-app.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 6 @app.route('/') 7 def hello_world(): 8 return 'Hello World!' 9 10 11 if __name__ == '__main__': 12 app.run()
2、Jinja2模板、自定义错误页面、静态文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask,render_template 2 3 app = Flask(__name__) 4 5 @app.route('/') 6 def index(): 7 return render_template('index.html') 8 9 @app.route('/user/<name>') 10 def user(name): 11 return render_template('user.html',name=name) 12 13 @app.route('/hello_world') 14 def hello_world(): 15 return 'Hello World!' 16 17 @app.errorhandler(404) 18 def page_not_found(e): 19 return render_template('404.html'),404 20 21 @app.errorhandler(500) 22 def errorhandler(e): 23 return render_template('500.html'),500 24 25 if __name__ == '__main__': 26 app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 {% block head %} 6 <title>----{% block title %}{% endblock %}----</title> 7 {% endblock %} 8 </head> 9 <body> 10 <p>Flask的Base页面</p> 11 {% block body %} 12 {% endblock %} 13 </body> 14 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 <!--head在基模板中不是空的,使用super()获取原本内容--> 3 {% block head %}{{ super() }}{% endblock %} 4 {% block title %}首页{% endblock %} 5 {% block body %}首页的body{% endblock %}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 {% block head %}{{ super() }}{% endblock %} 3 {% block title %}用户--{{ name }}{% endblock %} 4 {% block body %}{% endblock %}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 {% block head %}{{ super() }}{% endblock %} 3 {% block title %}404{% endblock %} 4 {% block body %} 5 <image src="{{ url_for('static',filename='images/404.jpg') }}"></image> 6 {% endblock %}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 {% block head %}{{ super() }}{% endblock %} 3 {% block title %}500{% endblock %} 4 {% block body %}<h1>500</h1>{% endblock %}
3、Web表单 | Flask-WTF
3.1 基础使用,form的创建和验证
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask,render_template 2 from flask_wtf import FlaskForm 3 from wtforms import StringField,SubmitField 4 from wtforms.validators import DataRequired,IPAddress 5 6 app = Flask(__name__) 7 app.config['SECRET_KEY'] = 'key1' 8 9 class NameForm(FlaskForm): 10 name = StringField('你叫啥:',validators=[DataRequired()]) 11 ip = StringField('IP地址:',validators=[IPAddress()]) 12 submit = SubmitField('提交;-)') 13 14 15 @app.route('/',methods=['GET','POST']) 16 def index(): 17 name = '' 18 ip = '' 19 form = NameForm() 20 print(name,ip) 21 if form.validate_on_submit(): 22 name = form.name.data 23 ip = form.ip.data 24 form.name.data='' 25 form.ip.data='' 26 return render_template('index.html',form=form,name=name,ip=ip) 27 28 @app.route('/user/<name>') 29 def user(name): 30 return render_template('user.html',name=name) 31 32 @app.route('/hello_world') 33 def hello_world(): 34 return 'Hello World!' 35 36 @app.errorhandler(404) 37 def page_not_found(e): 38 return render_template('404.html'),404 39 40 @app.errorhandler(500) 41 def errorhandler(e): 42 return render_template('500.html'),500 43 44 if __name__ == '__main__': 45 app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 <!--head在基模板中不是空的,使用super()获取原本内容--> 3 {% block head %}{{ super() }}{% endblock %} 4 {% block title %}首页{% endblock %} 5 {% block body %} 6 <p>首页的body</p> 7 <div> 8 Hello!{{ name }}---{{ ip }} 9 </div> 10 <div> 11 <form method="post" action=""> 12 {{ form.hidden_tag() }} 13 {{ form.name.label }}{{ form.name() }}<br> 14 {{ form.ip.label }}{{ form.ip() }}<br> 15 {{ form.submit() }} 16 </form> 17 </div> 18 {% endblock %}
3.2 Post/重定向/Get模式,用户会话存储数据
改善用户体验,在post提交后刷新页面不再弹框警告
全局变量session,将数据保存在客户端cookie中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask,render_template,session,redirect,url_for 2 from flask_wtf import FlaskForm 3 from wtforms import StringField,SubmitField 4 from wtforms.validators import DataRequired,IPAddress 5 6 app = Flask(__name__) 7 app.config['SECRET_KEY'] = 'key1' 8 9 class NameForm(FlaskForm): 10 name = StringField('你叫啥:',validators=[DataRequired()]) 11 ip = StringField('IP地址:',validators=[IPAddress()]) 12 submit = SubmitField('提交;-)') 13 14 15 @app.route('/',methods=['GET','POST']) 16 def index(): 17 form = NameForm() 18 if form.validate_on_submit(): 19 session['name'] = form.name.data 20 session['ip'] = form.ip.data 21 return redirect(url_for('index')) 22 return render_template('index.html',form=form,name=session.get('name'),ip=session.get('ip')) 23 24 @app.route('/user/<name>') 25 def user(name): 26 return render_template('user.html',name=name) 27 28 @app.route('/hello_world') 29 def hello_world(): 30 return 'Hello World!' 31 32 @app.errorhandler(404) 33 def page_not_found(e): 34 return render_template('404.html'),404 35 36 @app.errorhandler(500) 37 def errorhandler(e): 38 return render_template('500.html'),500 39 40 if __name__ == '__main__': 41 app.run()
3.3 Flash消息
从后端闪现消息给前端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask,render_template,session,redirect,url_for,flash 2 from flask_wtf import FlaskForm 3 from wtforms import StringField,SubmitField 4 from wtforms.validators import DataRequired,IPAddress 5 6 app = Flask(__name__) 7 app.config['SECRET_KEY'] = 'key1' 8 9 class NameForm(FlaskForm): 10 name = StringField('你叫啥:',validators=[DataRequired()]) 11 ip = StringField('IP地址:',validators=[IPAddress()]) 12 submit = SubmitField('提交;-)') 13 14 15 @app.route('/',methods=['GET','POST']) 16 def index(): 17 form = NameForm() 18 if form.validate_on_submit(): 19 old_name = session.get('name') 20 if old_name!=None and old_name!=form.name.data: 21 flash('小伙子,看来你改名了!') 22 session['name'] = form.name.data 23 session['ip'] = form.ip.data 24 return redirect(url_for('index')) 25 return render_template('index.html',form=form,name=session.get('name'),ip=session.get('ip')) 26 27 @app.route('/user/<name>') 28 def user(name): 29 return render_template('user.html',name=name) 30 31 @app.route('/hello_world') 32 def hello_world(): 33 return 'Hello World!' 34 35 @app.errorhandler(404) 36 def page_not_found(e): 37 return render_template('404.html'),404 38 39 @app.errorhandler(500) 40 def errorhandler(e): 41 return render_template('500.html'),500 42 43 if __name__ == '__main__': 44 app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 <!--head在基模板中不是空的,使用super()获取原本内容--> 3 {% block head %}{{ super() }}{% endblock %} 4 {% block title %}首页{% endblock %} 5 {% block body %} 6 <p>首页的body</p> 7 <div> 8 Hello!{{ name }}---{{ ip }} 9 </div> 10 <div> 11 <!--获取后台flash过来的内容--> 12 {% for message in get_flashed_messages() %} 13 {{ message }} 14 {% endfor %} 15 <form method="post" action=""> 16 {{ form.hidden_tag() }} 17 {{ form.name.label }}{{ form.name() }}<br> 18 {{ form.ip.label }}{{ form.ip() }}<br> 19 {{ form.submit() }} 20 </form> 21 </div> 22 {% endblock %}
4、数据库,ORM,Flask-SQLAlchemy
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from flask import Flask,render_template,session,redirect,url_for,flash 2 from flask_wtf import FlaskForm 3 from wtforms import StringField,SubmitField 4 from wtforms.validators import DataRequired,IPAddress 5 from flask_sqlalchemy import SQLAlchemy 6 7 app = Flask(__name__) 8 app.config['SECRET_KEY'] = 'key1' 9 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@127.0.0.1/world?charset=utf8' 10 app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True 11 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 12 db = SQLAlchemy(app) 13 14 class NameForm(FlaskForm): 15 name = StringField('你叫啥:',validators=[DataRequired()]) 16 ip = StringField('IP地址:',validators=[IPAddress()]) 17 submit = SubmitField('提交;-)') 18 19 class Role(db.Model): 20 __tablename__ = 'roles' 21 id = db.Column(db.Integer,primary_key=True) 22 name = db.Column(db.String(64),unique=True) 23 users = db.relationship('User',backref='role') 24 def __repr__(self): 25 return '<Role %r>'%self.name 26 27 class User(db.Model): 28 __tablename__ = 'users' 29 id = db.Column(db.Integer,primary_key=True) 30 username = db.Column(db.String(64),unique=True,index=True) 31 role_id = db.Column(db.Integer,db.ForeignKey('roles.id')) 32 def __repr__(self): 33 return '<Role %r>'%self.username 34 35 36 37 38 @app.route('/',methods=['GET','POST']) 39 def index(): 40 form = NameForm() 41 if form.validate_on_submit(): 42 user = User.query.filter_by(username=form.name.data).first() 43 if user is None: 44 user = User(username=form.name.data) 45 db.session.add(user) 46 session['known'] = False 47 else: 48 session['known'] = True 49 session['name'] = form.name.data 50 form.name.data='' 51 return redirect(url_for('index')) 52 return render_template('index.html',form=form,name=session.get('name'),ip=session.get('ip')) 53 54 @app.route('/user/<name>') 55 def user(name): 56 return render_template('user.html',name=name) 57 58 @app.route('/hello_world') 59 def hello_world(): 60 return 'Hello World!' 61 62 @app.errorhandler(404) 63 def page_not_found(e): 64 return render_template('404.html'),404 65 66 @app.errorhandler(500) 67 def errorhandler(e): 68 return render_template('500.html'),500 69 70 if __name__ == '__main__': 71 app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {% extends 'base.html' %} 2 <!--head在基模板中不是空的,使用super()获取原本内容--> 3 {% block head %}{{ super() }}{% endblock %} 4 {% block title %}首页{% endblock %} 5 {% block body %} 6 <p>首页的body</p> 7 <div> 8 Hello!{{ name }}---{{ ip }} 9 </div> 10 <div> 11 <h1>hello,{% if name %}{{ name }}{% else %}陌生人{% endif %}</h1> 12 {% if not know %} 13 <p>很高兴认识你</p> 14 {% else %} 15 <p>很高兴再见到你</p> 16 {% endif %} 17 <form method="post" action=""> 18 {{ form.hidden_tag() }} 19 {{ form.name.label }}{{ form.name() }}<br> 20 {{ form.ip.label }}{{ form.ip() }}<br> 21 {{ form.submit() }} 22 </form> 23 </div> 24 {% endblock %}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #配置数据库连接 2 app = Flask(__name__) 3 app.config['SECRET_KEY'] = 'key1' 4 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@127.0.0.1/world?charset=utf8' 5 app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True 6 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 7 db = SQLAlchemy(app) 8 9 #定义模型 10 class NameForm(FlaskForm): 11 name = StringField('你叫啥:',validators=[DataRequired()]) 12 ip = StringField('IP地址:',validators=[IPAddress()]) 13 submit = SubmitField('提交;-)') 14 15 class Role(db.Model): 16 __tablename__ = 'roles' 17 id = db.Column(db.Integer,primary_key=True) 18 name = db.Column(db.String(64),unique=True) 19 users = db.relationship('User',backref='role') 20 def __repr__(self): 21 return '<Role %r>'%self.name 22 23 #创建删除表,可以在flask shell中操作 24 db.create_all() 25 db.drop_all() 26 27 #增 28 admin_role = Role(name='Admin') 29 user1 = User(username='Jim',role=admin_role) 30 db.session.add(admin_role) 31 db.session.add(user1) 32 db.session.commit() 33 34 #查 35 #查全部,返回列表 36 Role.query.all() 37 #查单个,返回query对象 38 admin_role = Role.query.filter_by(name='Admin').first() 39 40 #删 41 db.session.delete(admin_role) 42 db.session.commit() 43 44 #改 45 admin_role.name = 'AD' 46 db.session.add(admin_role) 47 db.session.commit() 48 49 #回滚,在commit前都可以回滚到上次commit时的状态 50 db.seesion.rollback()
查看sql语句
str(Role.query.filter_by(name='Admin').first())