Flask学习总结

一、创建Flask实例

from flask import Flask
app = Flask(__name__)

 二、route()函数

 route()函数是一个装饰器,告诉应用程序,那个url应该调用相关的函数,如下方,http://127.0.0.1:5000/,即'/ ' URL调用hello world()函数
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 处理

Cookie以文本文件的形式存储在客户端计算机上。 其目的是记住和跟踪与客户使用有关的数据,以获得更好的访问体验和网站统计。

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会话

与Cookie不同,会话数据存储在服务器上。 会话是客户端登录到服务器并注销的时间间隔。 需要在此会话中进行的数据存储在服务器上的临时目录中。

与每个客户端的会话分配一个会话ID。 会话数据存储在cookie顶部,服务器以加密方式签名。 对于这种加密,Flask应用程序需要一个定义SECRET_KEY。

会话对象也是一个包含会话变量和关联值的键值对的字典对象。

1.要设置'username'会话变量,请使用语句 -  admin= session['username']
2.要删除会话变量,请使用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>
2.URL处理程序从request.files['file']对象中提取文件并将其保存到所需的位置。
3.每个上传的文件首先保存在服务器上的临时位置,然后再保存到最终位置。
TIPS:目标文件的名称可以是硬编码的,也可以从request.files [file]对象的filename属性中获取。 但是,建议使用secure_filename()函数获取它的安全版本。
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 SQLAlchem
Python工具包SQLAlchemy是一个功能强大的OR映射器,为应用程序开发人员提供了SQL的全部功能和灵活性。
Flask-SQLAlchemy是Flask扩展,使用Flask-SQLAlchemy的ORM技术可构建一个小型Web应用程序。
OR映射:数据模型是对象模型(Object)与存储模型是关系模型(Relational)是不一致的,需要在两者之间进行变换即OR映射。
ORM对象关系映射:ORM API提供了执行CRUD操作的方法,而无需编写原始SQL语句,解决了对象和关系型数据库之间的数据交互问题。
CRUD:是指数据库增加(Create)、读取(Read)、更新(Update)和删除(Delete)操作单词的首字母简写。
 
SQLAlchemy的Session对象管理ORM对象的所有持久性操作。
以下会话方法执行CRUD操作 :
db.session.add(模型对象) - 将一条记录插入到映射表中
db.session.delete(模型对象) - 从表中删除记录
model.query.all() - 从表中检索所有记录(对应于SELECT查询),或者用filter_by。
如要在students表中检索city ='Haikou'的记录,执行语句如:Students.query.filter_by(city = 'Haikou').all()
实例:
from 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

十一、Flask Sijax
Sijax代表’Simple Ajax’,它是一个Python/jQuery库,旨在帮助Flask开发者轻松地将Ajax引入到应用程序。 它使用jQuery.ajax来发出AJAX请求。
Sijax使用JSON在浏览器和服务器之间传递数据。因此,浏览器需要本地支持JSON或从json2.js文件获得Ajax:Asynchronous Javascript And XML,是用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScriptDOM, XML, XSLT, 以及最重要的XMLHttpRequest。使用Ajax技术网页应用能够快速地将增量更新呈现在用户界import flask_sija
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')会报错,还未确定原因。

posted @ 2022-09-30 10:10  不不田鼠  阅读(124)  评论(0编辑  收藏  举报