Flask筆記

官方文檔: http://flask.pocoo.org/docs/0.11/
中文文檔: http://docs.jinkan.org/docs/flask/

HTTP協議:

  1. 請求
    • 請求行
    • 請求頭
    • 請求體
  2. 響應
    • 響應行

      • HTTP / 1.1 200 OK

      • 響應狀態:

      • 200:響應成功
      • 302:重定向
      • 304:資源未更新
      • 404:資源不存在
      • 500:服務器內部錯誤

  • 鍵值對:說明

​ Content-Type:文件類型 text/html image/jpeg application/json text/xml

  • 響應體

1.定義正則:

1.導包
from werkzeug.routing import BaseConverter
2.創建正則類,重寫__init__方法,並調用父類方法
class XXXX(BaseConverter):
    def __init__(self, url_map, *args):                                                              super(XXXX,self).__init__(url_map)
        self.regex = args[0]
3.添加至app
# 創建Flask對象
app = Flask(__name__)
app.url_map.converters['re'] = XXXX
# 視圖入口
if __name__ == "__main__":
    app.run(debug=True)  # 調試模式

2.傳參

  • 在@app.route(‘/<>’)路由中添加可變參數: <id>
  • 規定參數類型:<int:id>
  • 引用正則:<re('[a-z]'):id>

3.返回JSON數據

  1. 導入json數據包
  2. 調用返回:json.jumps(json-data)

4.狀態碼

def ret():
    return 'data',  200
# 拋出異常,404代表異常類型
def abort_test();
    abort(404)
    return 'data'  # 可以返回字符串,Flask自動封裝爲響應對象
自定義狀態碼視圖
@app.errorhandler(500)  # 註冊狀態碼處理函數
def error_test(value):
    return '服務器忙...'

5.上下文對象(request.response)

  1. request

  2. sesion

  3. current_app

  4. g

    (response)

Flask 封裝request和response爲全局對象

request方法:

方法 解釋
args 一個包含解析過的查詢字符串( URL 中問號後的部分)內容的 MultiDict
form 一個包含解析過的從 POST 或 PUT 請求發送的表單對象的 MultiDict 。請注意上傳的文件不會在這裏,而是在 files 屬性中
value 一個包含 form 和 args 全部內容的 CombinedMultiDict
cookies 一個包含請求中傳送的所有 cookie 內容的 dict
headers 進入請求的標頭存爲一個類似字典的對象
files 一個包含 POST 和 PUT 請求中上傳的文件的 MultiDict. 包含save()方法
method 當前請求的 HTTP 方法
如下參考完整url信息 http://www.example.com/myapplication/page.html?x=y
path /page.html
script_root /myapplication
base_url http://www.example.com/myapplication/page.html
url http://www.example.com/myapplication/page.html?x=y
url_root http://www.example.com/myapplication/

response方法:

方法 解釋
headers Headers 對象用於設置響應的頭信息
status 用於設置響應狀態描述
status_code 整數,用於設置響應狀態碼
mimetype 用於設置響應的MIME類型
set_cookie() 設置cookie

示例:

response = make_response('顯示文字')  # 創建response對象
response.set_cookie(key, value)  # 設置cookie

request.headers.get('User-Agent')  # 獲取請求頭中內容

session['key'] = value  # 設置session
session.get('key')  # 獲取session

6.應用上下文current_app和變量g

current_app 可以獲取當前app所在環境信息(ip,內存等)

current_app.name  # 獲取應用名稱
current_app.test_value='value'  # 利用應用上下文存取變量
g.name='abc'  # 臨時性全局變量

*手動創建應用上下文:應用上下文只存在於當前主線程中,額外創建的子線程中需要手動創建

with app.app_context():
    other_code_for_you

7.Flask擴展包

  • Flask-SQLalchemy:操作數據庫;
  • Flask-Migrate:管理遷移數據庫;
  • Flask-Mail:郵件;
  • Flask-WTF:表單;
  • Flask-Bable:提供國際化和本地化支持,翻譯;
  • Flask-Script:插入腳本;
  • Flask-Login:認證用戶狀態;
  • Flask-OpenID:認證;
  • Flask-RESTful:開發REST API的工具;
  • Flask-Bootstrap:集成前端Twitter Bootstrap框架;
  • Flask-Moment:本地化日期和時間;

8.Flask_script擴展

from flask import Flask
from flask_script import Manager  # 導入
app = Flask(__name__)
manager = Manager(app)  # 註冊
@app.route('/')
def index():
    return '牀前明月光'
if __name__ == "__main__":
    manager.run()  # 使用

9.Flask-Script插件

添加管理功能:

pip install Flask-Script # 安裝

from flask_script import Manager
app = Flask(__name__)
...
manager = Manager(app)
...
manager.run()

python app.py runserver # 運行

測試的命令行環境(調試):

python app.py shell
...  # 修改調試上下文(app.app_context()返回current_app)
...  # app.test_request_ctx()

… 上下文對象存儲於棧結構中:先進後出,後進先出

10.模板

  • 模板語言

    • 代碼塊: {{ }}

    • 邏輯代碼: {% %} 也可以使用過濾器

      • {{ loop.index }} # 返回循環索引,從1開始
      • {{ loop.cycle('1', 'a', 'c') }} # 返回cycle中作爲索引
    • 禁止解析: {% raw %} <script>js處理</script> {% raw %}

    • 過濾器: {{ variable | filter_name(*args) }} # *args在沒有條件的情況下可以省略

      示例:

      • {{ 111 | float }}
      • {{ 111.11 | int }}
      • {{ [python , flask] | join(',')}}
      • {{ '123' | length }}
      • {{ 3.1415 | round(2) }} # 四捨五入
      • {{ 4.22 | round(1, 'common') }} # 四捨五入
      • {{ 4.28 | round(1, 'floor') }} # 舍位
      • {{ 4.22 | round(1, 'ceil') }} # 進位
      • {{ {'key': 'value'} | tojson }} # json輸出
      • {{ 'abcdefg' | truncate(3, True) }} # 截取,True代表包含空格
      • {{ False_args | default('Treu_args, True') }} # 變量爲假時,替換爲default值
      • {{ '%s is %d' | format('name',17) }} # 格式化輸出
      • {{ ' hello world ' | trim }} # 去掉首尾空格
      • {{ '<em>hello</em>' | striptags }} # 渲染前去掉HTML標籤
      • title upper lower capitalize等
    • 自定義過濾器

      app.jinjia_env.filters['key'] = filter_function # 註冊過濾器函數

  • 模板渲染

    模板文件放在項目根目錄下templates目錄下

    • render_template('index.html')
  • 模板傳參

    • render_template('index.html', name=name, pwd=pwd)

11.宏

實現HTML代碼重用(類似於代碼公共部分抽取,繼承)

{% macro func(name,label,value='',type='text') %}
    <input type="{{type}}" name="{{name}}"
            value="{{value|escape}}" class="form-control">
{% endmacro %}

調用:

func(name, 'username') # 當前文件調用

封裝爲文件:

{% macro function() %}
    <div class="form-group">
        <input type="{{type}}" name="{{name}}"
            value="{{value|escape}}" class="form-control">
    </div>
{% endmacro %}

其他文件調用:

{% import 'macro.html' as func %}
{% func.function() %}

12.模板繼承

調用父類模板內容

{% block content %}
{% super() %}
... // 自定義內容
{% endblock %}

13.Flask 特有變量和函數

url_for() # 獲取視圖函數對應的url

redirect(url_for('views_function')) # 重定向(發送兩次請求,地址欄改變)

設置: app.config['aaa']='xxx' 獲取: {{config.aaa}} # 作爲配置文件信息使用

設置: session['aaa']='xxx' 獲取: {{session.get('aaa')}}

flash('a')=b  # 應用中設置


{%for message in get_flashed_messages()%}
    {{message}}  // 獲取輸入框提示信息等
{%endfor%}

14.Form

1.WTF–簡化form生成以及驗證過程

常用字段:

常用字段

表單內容驗證函數:

表單驗證函數

from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField
from wtforms.validators import DataRequired,EqualTo

class Login(FlaskForm):
​   username = StringField(lable='用戶名', validators=[DataRequired()])
​   password = PasswordField(label='密碼', validators=[DataRequired(),                    EqualTo('ps2','err')])
​   submit = SubmitField('提交')
# u(原生字符)可以使用如下代碼替代:
    app.config['SECRET_KEY'] = 'abc'  # 非對稱加密公鑰

@app.route('/register')
def register():
    form = login()  # 創建對象
    return render_template('register.html', form=form)
<form method="post" action="">
    {{ form.csrf_token() }}
    {{ form.username.label }}
    <p>{{ form.us }}</p>
    {{ form.password.label }}
    <p>{{ form.ps }}</p>
    <p>{{ form.submit() }}</p>
    {% for x in get_flashed_messages() %}
        {{ x }}
    {% endfor %}
</form>
@app.route('/',methods=['GET','POST'])
def index():
    form = Login()
    if form.validate_on_submit():  # 表單提交有效性驗證
        name = form.username.data  # 兩種獲取方式
        pswd = request.form['password']
        return redirect(url_for("success"))
    else:
        if request.method=='POST':
            flash(u'信息有誤,請重新輸入!')
        print form.validate_on_submit()

    return render_template('index.html',form=form)
2.原生
from flask import Flask
app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST']) # 默認爲GET請求(渲染頁面),需要添加POST(提交表單)
def  login():   
    if request.method == 'POST':
        # 第二次請求使用POST
        username = requst.forms['username']   # 表單中無action=''提交路徑,默認返回當前頁面
    # 第一次訪問,渲染表單頁面
    return render_template('login.html', method=request.method)

@app.route('/login_handle', methods=['POST']) # 一般提交至第二個視圖處理,默認爲GET請求,需要添加POST
def login_handle():
    username = request.forms['username']  # 獲取表單數據
    return ...

if __name__ == '__main__':
    app.run()

15.SQLALchemy

Flask中關係型擴展,用來操作數據庫

1.配置:

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user_name:[email protected]:3306/database_name'

2.常用字段類型:

字段類型

​ 字段約束類型:

  • 主鍵約束:唯一且非空
  • 唯一約束:可以爲null,但非null不可重複
  • 非空約束:not null
  • 外鍵約束:區關聯主鍵,或者null

3.常用列選項:

列選項

4.常用關係選項:

關係選項

一對多
class Role(db.Model):
    ...
# 關鍵代碼
    us = db.relationship('User', backref='role', lazy='dynamic')
    ...

class User(db.Model):
    ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

backref 爲類User申明新屬性的方法

lazy 決定了什麼時候SQLALchemy從數據庫中加載數據,如果設置爲子查詢方式subquer ,則會在加載完User對象後,就立即加載與其關聯的對象,這樣會讓總查詢數量減少,但如果返回的條目數量很多,就會比較慢,另外,也可以設置爲動態方式dynamic ,這樣關聯對象會在被使用的時候再進行加載,並且在返回前進行過濾,如果返回的對象數很多,或者未來會變得很多,那最好採用這種方式

多對多
registrations = db.Table('registrations',  
    db.Column('student_id', db.Integer, db.ForeignKey('students.id')),  
    db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))  
)  
class Course(db.Model):
    ...
class Student(db.Model):
    ...
    classes = db.relationship('Course',secondary=registrations,  
                                backref='student',  
                                lazy='dynamic')"

registrations 爲格外創建的關聯表

5.創建表以及插入數據

db.create_all()
data1 = Student(name = '1')
db.session.add(data1)    # 或者 db.session.add_all([data1, data2])
db.session.commit()

6.查詢

常用SQLAlchemy查詢過濾器

圖片4

常用查詢執行器

圖片5

邏輯與:and_()

邏輯或:or_()

邏輯非:not_()

7.刪除查詢對象

stu1 = Student.query.first()
db.session.delete(stu1)
db.session.commit()

8.更新數據

stu1 = Student.query.first()
stu1.name = 'new_name'
db.session.commit()

16.數據庫遷移flask-migrate

準備:

migrate = Manager(app, db)
manager = Manager(app)
manager.add_command('db', MiagrateCommand) # 註冊至flask-script,方便在命令行管理

操作:

python app.py db init # 初始化  # db 爲add_command()中設置的名稱
python app.py db migrate -m'版本名' # 創建遷移文件,版本參數可以省略
python app.py db upgrade # 遷移
python app.py db history  # 歷史版本
python app.py db downgrade 版本號  # 回滾

傳入shell對象字典,避免每次shell操作導入

def make_shell_context():
    return dict(app=app, db=db,...)
manager.add_command('shell', Shell(make_context=make_shell_context))

17.發送郵件flask-mail

1.配置:(服務器,端口,安全套接字層/傳輸安全層協議,郵箱名,密碼等)

app.config['MAIL_SERVER'] = 'smtp.126.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME']=
app.config['MAIL_PASSWORD']=
app.config['MY_MAIL_SENDER'] =   #發送者
app.config['MY_MAIL_TO']=   # 接收者

2.註冊:

mail= Mail(app)

3.設置消息:

msg = Message(subject, sender='', recipientes=['to_1'], ...)
msg.body=''   或者   msg.html=''

4.發送:

mail.send(msg)

18.flask-bootstrap

bootstrap = Bootstrap(app)

19.flask-Moment(未完成)

moment = Moment(app)
moment.include_moment()

20.Blueprint

將項目文件模塊化

1.創建藍圖對象

login = Blueprint('login', __name__,static_folder='', template_folder='')
# 同名文件,系統默認使用項目下默認的templates下文件,可以使用相對路徑避免此問題

2.註冊路由,指定靜態文件夾,模板文件夾

@login.route('/')
def login_index():
    return 'login_index'

@login.route('/handle)
def login_handle():
    return 'login_handle'

3.在應用對象上註冊藍圖

app.register_blueprint(login, url_prefix='/login')

static_url_path :可以爲當前藍圖靜態文件目錄指定一個別名

使用url_for查詢視圖函數:url_for('login.login_index')

發佈了42 篇原創文章 · 獲贊 28 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章