Flask学习总结
一、创建Flask实例
from flask import Flask app = Flask(__name__)
二、route()函数
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World' if __name__ == '__main__': app.run()
三、run()方法
Flask类的run()方法,启动开发服务器
四、Jinja2模板引擎分隔符
{% ... %} 用于多行语句
{{ ... }} 用于将表达式打印输出到模板
{# ... #} 用于未包含在模板输出中的注释
# ... ## 用于单行语句
例子1:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask模板示例</title> </head> <body> {% if marks>50 %} <h1> 通过考试!</h1> {% else %} <h1>未通过考试!</h1> {% endif %} </body> </html>
例子2:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask模板示例</title> </head> <body> <table border = 1> {% for key, value in result.items() %} <tr> <th> {{ key }} </th> <td> {{ value }} </td> </tr> {% endfor %} </table> </body> </html>
五、Flask Cookies 处理
1.make_response()函数从视图函数的返回值中获取响应对象
2.使用响应对象的set_cookie()函数来存储cookie
3.使用request.cookies属性的get()方法来读取cookie
from flask import Flask from flask import render_template from flask import request from flask import make_response app = Flask(__name__) @app.route('/') def index(): return render_template('index_cookies.html') @app.route('/setcookie', methods = ['POST', 'GET']) def setcookie(): if request.method == 'POST': user = request.form['name'] resp = make_response('success')#函数从视图函数的返回值中获取响应对象 resp.set_cookie('userID', user)#存储cookie return resp @app.route('/getcookie') def getcookie(): name = request.cookies.get('userID')#读取cookie return '<h1>welcome, '+name+'</h1>' if __name__ == '__main__': app.run()
六、Flask Session会话
与每个客户端的会话分配一个会话ID。 会话数据存储在cookie顶部,服务器以加密方式签名。 对于这种加密,Flask应用程序需要一个定义SECRET_KEY。
会话对象也是一个包含会话变量和关联值的键值对的字典对象。
'username'
会话变量,请使用语句 - admin= session['username']pop()
方法。如:session.pop('username', None)# coding=utf8 #@Time:2022/9/14 from flask import Flask, session, redirect, url_for,request app = Flask(__name__) app.secret_key = 'fkdjsafjdkfdlkjfadskjfadskljdsfklj' @app.route('/') def index(): if 'username' in session: username = session['username'] return '登录用户名是:' + username + '<br>' +"<b><a href = '/logout'>点击这里注销</a></b>" #对应/logout return "您暂未登录, <br><a href = '/login'></b>" +"点击这里登录</b></a>" #对应/login @app.route('/login', methods = ['GET', 'POST']) def login(): if request.method == 'POST': session['username'] = request.form['username'] return redirect(url_for('index')) return ''' <form action = "" method = "post"> <p><input type ="text" name ="username"/></p> <p><input type ="submit" value ="登录"/></p> </form> ''' @app.route('/logout') def logout(): # remove the username from the session if it is there session.pop('username', None) return redirect(url_for('index')) if __name__ == '__main__': app.run()
七、Flask上传文件
1.HTML表单里需要增加一个enctype = "multipart/form-data"属性设置,将该文件提交到指定URL。<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask示例</title> </head> <body> <form action = "http://localhost:5000/upload" method = "POST" enctype = "multipart/form-data"> <input type = "file" name = "file" /> <input type = "submit" value="提交"/> </form> </body> </html>
from flask import Flask, render_template, request from werkzeug.utils import secure_filename app = Flask(__name__) @app.route('/upload', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': f = request.files['file']#提取文件并将其保存到所需位置 print(request.files) f.save(secure_filename(f.filename)) return 'file uploaded successfully' else: return render_template('upload.html') if __name__ == '__main__': app.run()
八、Flask发送邮件
from flask import Flask from flask_mail import Mail, Message app = Flask(__name__) #以下是邮件配置 app.config['MAIL_SERVER']='smtp.qiye.163.com' app.config['MAIL_PORT'] = 465 app.config['MAIL_USERNAME'] = '发送方邮箱' app.config['MAIL_PASSWORD'] = '发送方邮箱密码' app.config['MAIL_USE_TLS'] = False app.config['MAIL_USE_SSL'] = True #创建一个Mail类实例 mail = Mail(app) @app.route("/") def index(): #设置邮件信息 msg = Message('Hello', sender = '发送方邮箱', recipients = ['接受方邮箱']) #设置邮件内容 msg.body = "This is the email body" #发送邮件 mail.send(msg) return "Sent" if __name__ == '__main__': app.run()
九、Flask的WTF
使用Flask-WTF,可以在Python脚本中定义表单域并使用HTML模板来呈现它们。 也可以将验证应用于WTF字段。
1.字段类型说明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密码文本字段
HiddenField 隐藏文本字段
DateField 文本字段,值为 datetime.date 格式
DateTimeField 文本字段,值为 datetime.datetime 格式
IntegerField 文本字段,值为整数
DecimalField 文本字段,值为 decimal.Decimal
FloatField 文本字段,值为浮点数
BooleanField 复选框,值为 True 和 False
RadioField 一组单选框
SelectField 下拉列表
SelectMultipleField 下拉列表,可选择多个值
FileField 文件上传字段
SubmitField 表单提交按钮
FormField 把表单作为字段嵌入另一个表单
FieldList 一组指定类型的字段
2.WTForms验证函数说明Email 验证电子邮件地址
EqualTo 比较两个字段的值;常用于要求输入两次密码进行确认的情况
IPAddress 验证 IPv4 网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其他验证函数
Required 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证 URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选值列表中
实例:
from flask import Flask, request, flash, render_template, url_for, redirect from app_13_flask_wtf_forms import ContactForm app = Flask(__name__) app.secret_key = 'development key' #模仿的例子 # @app.route('/', methods = ['GET', 'POST']) # def contact(): # form = ContactForm() # # if request.method == 'POST': # if form.validate() == False: # flash('All fields are required.') # return render_template('contact.html', form = form) # else: # return '提交成功~' # elif request.method == 'GET': # return render_template('contact.html', form = form) # @app.route('/', methods = ['GET', 'POST']) def contact1(): form = ContactForm() if request.method == 'POST': return'提交成功~' else: return render_template('contact.html', form=form) if __name__ == '__main__': app.run()
from flask_wtf import Form from wtforms import IntegerField, TextAreaField, SubmitField, RadioField, SelectField, validators, StringField from wtforms.validators import DataRequired, length, Email, NumberRange class ContactForm(Form): #validators是做数据验证 name = StringField("学生姓名",validators=[DataRequired('姓名必填~'),length(2,6,message="Please enter the correct name.")]) Gender = RadioField('性别', choices = [('M','Male'),('F','Female')]) Address = TextAreaField("地址",validators=[DataRequired(),length(1,20)]) email = StringField("Email",validators=[DataRequired(),length(1,10),Email(message='Please enter the correct Email.')]) Age = IntegerField("年龄",validators=[NumberRange(2,90)] ) language = SelectField('语言', choices = [('cpp', 'C++'), ('py', 'Python')]) submit = SubmitField("提交")
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask示例</title> </head> <body> <h2 style = "text-align: center;">联系人表单</h2> <!--{% for message in form.name.errors %}--> <!--<div>{{ message }}</div>--> <!--{% endfor %}--> <!--{% for message in form.email.errors %}--> <!--<div>{{ message }}</div>--> <!--{% endfor %}--> <form action = "/" method = post> <fieldset> <legend>填写项</legend> {{ form.hidden_tag}} <div style = font-size:20px; font-weight:bold; margin-left:150px;> {{ form.name.label }}<br> {{ form.name }} <br> {{ form.Gender.label }} {{ form.Gender }} {{ form.Address.label }}<br> {{ form.Address }} <br> {{ form.email.label }}<br> {{ form.email }} <br> {{ form.Age.label }}<br> {{ form.Age }} <br> {{ form.language.label }}<br> {{ form.language }} <br> {{ form.submit }} </div> </fieldset> </form> </body> </html>
HTML部分问题:1)之前是form.hidden_tag(),报错,去掉了小括号后解决问题 2)注释的部分没搞明白怎么用,填写无问题也会报,于是去掉,再继续研究
app.run()部分问题:注释部分是之前的代码,并没感觉到有执行到if,于是就改成简化版了,先跑起来再说吧
ContactForm部分问题:根据上面的字段类型和验证函数,对长度、必填项、提示语做了修改。1)目前看当前的代码,长度无问题可用;2)必填项配合HTML注释的部分用,会把之前的英文提示显示成中文;3)提示语未看到效果。
十、Flask SQLAlchemfrom flask import Flask, request, flash, url_for, redirect, render_template from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3' app.config['SECRET_KEY'] = "random string" #创建SQLAlchemy类的对象 db = SQLAlchemy(app) #创建学生模型 class students(db.Model): id = db.Column('student_id', db.Integer, primary_key = True) name = db.Column(db.String(100)) city = db.Column(db.String(50)) addr = db.Column(db.String(200)) pin = db.Column(db.String(10)) def __init__(self, name, city, addr,pin): self.name = name self.city = city self.addr = addr self.pin = pin @app.route('/') def show_all(): return render_template('show_all.html', students = students.query.all() )#students.query.all()从students表中检索所有记录 @app.route('/new', methods = ['GET', 'POST']) def new(): if request.method == 'POST': if not request.form['name'] or not request.form['city'] or not request.form['addr']: flash('Please enter all the fields', 'error') else: student = students(request.form['name'], request.form['city'],request.form['addr'], request.form['pin']) print(student) #SQLAlchemy的Session对象管理ORM对象的所有持久性操作 #将一条记录插入到映射表中 db.session.add(student) db.session.commit() flash('Record was successfully added') return redirect(url_for('show_all')) return render_template('new.html') if __name__ == '__main__': app.run()
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask示例</title> </head> <body> <h3> <a href = "{{ url_for('show_all') }}">学生列表 - Flask SQLAlchemy示例</a> </h3> <hr/> {%- for message in get_flashed_messages() %} {{ message }} {%- endfor %} <h3>学生 (<a href = "{{ url_for('new') }}">添加 </a>)</h3> <table> <thead> <tr> <th>姓名</th> <th>城市</th> <th>地址</th> <th>Pin</th> </tr> </thead> <tbody> {% for student in students %} <tr> <td>{{ student.name }}</td> <td>{{ student.city }}</td> <td>{{ student.addr }}</td> <td>{{ student.pin }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
↑↑↑show_all.html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flask示例</title> </head> <body> <h3>学生信息 - Flask SQLAlchemy示例</h3> <hr/> {%- for category, message in get_flashed_messages(with_categories = true) %} <div class = "alert alert-danger"> {{ message }} </div> {%- endfor %} <form action = "{{ request.path }}" method = "post"> <label for = "name">姓名</label><br> <input type = "text" name = "name" placeholder = "Name" /><br> <label for = "email">城市</label><br> <input type = "text" name = "city" placeholder = "city" /><br> <label for = "addr">地址</label><br> <input name = "addr" placeholder = "addr"/><br> <label for = "PIN">邮编</label><br> <input type = "text" name = "pin" placeholder = "pin" /><br> <input type = "submit" value = "提交"/> </form> </body> </html>
↑↑↑new.html
import os import flask_sijax from flask import Flask, g, render_template path = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/') app = Flask(__name__) app.config['SIJAX_STATIC_PATH'] = path #Sijax javascript文件的静态路径。 默认位置是static/js/sijax。 在这个文件夹中,保存了sijax.js和json2.js文件。 app.config['SIJAX_JSON_URI'] = '/static/js/sijax/json2.js'#加载json2.js静态文件的URI flask_sijax.Sijax(app) @app.route('/') def index(): return "Hello World!<br><a href = '/hello'>Go to Sijax test</a>" @flask_sijax.route(app, '/hello') def hello(): def say_hi(obj_response):#obj_response就像Python的self,是函数返回浏览器的对象 obj_response.alert('Hi there!') if g.sijax.is_sijax_request:#以下两行是Sijax接到请求后处理方法 g.sijax.register_callback('say_hi', say_hi)#注册的函数都公开给浏览器进行调用 return g.sijax.process_request()#告诉Sijax执行适当的(之前注册的)函数并将响应返回给浏览器 return render_template('sijaxexample_01.html') if __name__ == '__main__': app.run()
sijaxexample_01.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> {# 调用百度的jQuery加速 #} <script type="text/javascript" src="https://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> {# 安装Flask-sijax时默认安装的sijax.js #} <script type="text/javascript" src="/static/js/sijax/sijax.js"></script> {# 使用过滤器safe禁止转译sijax.get_js()值 #} <script type="text/javascript"> {{ g.sijax.get_js()|safe }} </script> <title>sijaxexample</title> </head> <body> <form id="my_form"> <input type="text" name="tbx1" value="textbox 1"> <input type="text" name="tbx2" value="textbox 2"> <input type="checkbox" name="cbx" value="checked"> </form> <!--<script type="text/javascript">--> <!--let values=Sijax.getFormValues('#my_form');--> <!--</script>--> <!--<a href="javascript://" onclick="Sijax.request('say_hi',[values]);">click</a>--> <a href="javascript://" onclick="Sijax.request('say_hi');">click</a> </body> </html>
注销部分是因为let values=Sijax.getFormValues('#my_form')会报错,还未确定原因。
一切技术都是为业务服务,脱离业务的技术一文不值!