天天看點

python -flask簡介

__name__

__name__ 表示目前子產品的名稱

如果__name__ 在運作子產品中,顯示為__main__

如果作為子產品被導入,則為子產品名稱

執行檔案時輸出__main__

python -flask簡介

被當做子產品引入輸出子產品名稱

Flask執行個體化

# __name__ 目前子產品的名字,flask以子產品所在的目錄為總目錄
app = Flask(__name__,
            # 靜态檔案存放目錄,預設static
            static_folder="dome",
            # 靜态檔案通路url, 預設static
            static_url_path="/python",
            # 模闆存放目錄,預設templates
            template_folder="dome_temp")
           

config

讀取參數配置

# 擷取配置檔案中的變量 
print(app.config.get("name")) 

# 通過current_app擷取參數 
print(current_app.config.get("name"))
           

url_map

# 通過url_map可以檢視整個flask中的路由資訊
print(app.url_map)
           
python -flask簡介

methods

# 視圖函數,可以接收GET,POST請求
@app.route("/", methods=["GET", "POST"])
def dome():
    return "post or get"
           

url_for

@app.route("/login")
def login():
    # 使用url_for的函數,通過視圖函數名稱解析為其url
    # redirect重定向
    return redirect(url_for("index"))



# 傳遞參數
 return redirect(url_for("index"),name="lisi")
           

擷取請求參數

flask中表示目前請求的request對象,request中儲存了一次HTTP請求的一切資訊。

data 記錄請求的資料,并轉換為字元串 ,類型 *

form 記錄請求中的表單資料   ,類型 MultiDict

args 記錄請求中的查詢參數 ,類型 MultiDict

files 記錄請求上傳的檔案 ,類型 *

示例:

from flask import Flask, request

app = Flask(__name__)


@app.route("/data", methods=["GET", "POST"])
def dataView():
    # json 等body送出的非表單資料,讀取請求體中資料
    rest = request.data
    # 表單送出的資料,如果表單中由相同key,預設傳回第一個key的參數,
    # 如果想要都獲得請使用getlist,讀取請求體中資料
    rest1 = request.form.get("lisi")
    # 擷取url後傳的參數
    rest2 = request.args.get("lisi")
    # 擷取上傳的檔案對象
    pic = request.files.get(("pic"))
    # 儲存圖檔
    pic.save("./1.png")
    print("url傳參%s" % rest2)
    print("表單送出%s" % rest1)
    print("data送出%s" % rest)

    return "ok"


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5678)
           

cookies 記錄請求中的cookies值 ,類型 Dict

headers 記錄請求中的封包頭 ,類型 EnvironHeaders

method 記錄請求使用的HTTO方法 ,類型 GET/POST

url 記錄請求的URL位址   ,類型 string

響應資訊

from flask import Flask, request, render_template, url_for, redirect, abort, make_response


@app.route("/xy")
def index():
    # 響應體  狀态碼  響應頭
    # 傳回順序不能錯
    # return "hello", 200, {"he": "side"}

    # 響應體
    rest = make_response("hello")
    # 狀态碼
    rest.status = 208
    # 響應頭
    rest.headers["HE!"] = "sude"
    return rest
           

render_template

# 傳回渲染後的html頁面,預設靜态頁存放在根目錄的templates下
return render_template("index.html")

# 模闆變量
{{ name }}
# 清單
{{list[3]}}
# 字典
{{mydic["key"]}}
# 對象
{{obj.methed()}}


# 過濾器
# 值的首字母大寫
<h1>Hello, {{ name|capitalize }}</h1>


# 控制結構
{% if name %}
    <h1>Hello, {{ name|capitalize }}</h1>
{% else %}
    <h1>Hello, Flask </h1> 
{% endif %}

# 循環
<ul>
{% for num in nums %}
   <li>{{ num }}</li> 
{% endfor %}
</ul>

# 宏,類似于函數
# 建立一個宏
{% macro render_comment(comment) %}
<li>{{ comment }}</li>
{% endmacro %}

# 引入
{% import 'macros.html' as macros %}

{% block page_content %}
<div class="page-header">
    # 使用
    <ul>
        {% for num in nums %}
            {{macros.render_comment(num)}}
        {% endfor %}
    </ul>
</div>
{% endblock %}

# 模闆繼承
{% extends "base.html" %}

# 繼承父模闆的js
{% block scripts %}
{{super()}}
# 增加自己的js
{{ moment.include_moment() }}
{% endblock %}



           

abort

@app.route("/link/<name>")
def link_url(name):
    if name == "lisi":
        # 抛出異常
        abort(404)
    return name
           

自定義錯誤頁

# 自定義404異常
@app.errorhandler(404)
# 試圖函數需要有參數來接收異常資訊
def page_not_found(e):
    print(e)
    # 傳回異常模闆資訊和狀态碼
    return render_template('404.html'), 404
           

flsak-Bootstrap

# 安裝 
pip install flask-bootstrap

# 初始化
from flask_bootstrap import Bootstrap
bootstrap = Bootstrap(app)

# 初始化完成後,bootstrap提供一個包含所有Bootsrtap檔案的基模闆我們利用jinja2的模闆繼承機制,可以衍生出自己的基模闆
----------------------
base.html

# 引入bootstrap基模闆
{% extends "bootstrap/base.html" %}

# title 塊 -- 标題
{% block title %}Flasky{% endblock %}

# navbar 塊   --- 導航
{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"
                    data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

# content 塊 ---主體内容
{% block content %}
    {% block mycontent %}
    
    {% endblock %}
<div class="container">
    <div class="page-header">
    {% block page_content %}{% endblock %}
    </div>
</div>

{% endblock %}


# scripts 塊  --底部的js
{% block scripts %}
# 繼承父級js
{{super()}}
# 添加自己的js檔案
<scripts type="text/javascripts" src="my.js"></scripts>
{% endblock %}

           

自定義基模闆示例:

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"
                    data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
    {% block mycontent %}
    
    {% endblock %}
<div class="container">
    <div class="page-header">
    {% block page_content %}{% endblock %}
    </div>
</div>
{% endblock %}



{% block scripts %}
{{super()}}
{{ moment.include_moment() }}
{% endblock %}
           

自定義錯誤頁

# 自定義404異常
@app.errorhandler(404)
# 試圖函數需要有參數來接收異常資訊
def page_not_found(e):
    print(e)
    # 傳回異常模闆資訊和狀态碼
    return render_template('404.html'), 404

--------
404.html


# 繼承自己編寫的基模闆
{% extends "base.html" %}
# 修改模闆标題
{% block title %} Flasky - Page Not Found {% endblock %}
# 修改模闆中内容
{% block page_content %}
<div class="page-header">
    <h1>404 Not Found</h1>
</div>
{% endblock %}
           

flask_moment

# 安裝
pip install flask_moment

# 初始化
from flask_moment import Moment
moment = Moment(app)

# flask_moment還是依賴jquery.js,bootstrap已經引入jquery.js,是以我們在基模闆隻需引入moment.js即可
----
base.html

#…………
{% block scripts %}
{{super()}}
{{ moment.include_moment() }}
{% endblock %}


# 使用示例
index.html
-----
{% extends "base.html" %}
{% block title %} Flasky {% endblock %}
{% block page_content %}
<div class="page-header">
    <h1>Hello, flask</h1>
    <!-- format參數決定了渲染方式 L 到 LLL 複雜度不同    -->
    <p> The local data time is {{moment(current_time).format('LLL')}}</p>
    <!--  fromNow 渲染相對時間,而且回随着時間的推移自動重新整理refresh 設定為True會自動更新  -->
    <p> That was {{moment(current_time).fromNow(refresh=True)}}</p>
</div>
{% endblock %}

methods
-----
from datetime import datetime
@app.route("/times")
def index():
    return render_template("index.html", current_time=datetime.utcnow())
           

表單

# 安裝
pip install  flask-wtf
# 引入
from wtforms import Form, SubmitField, StringField, PasswordField, BooleanField
from wtforms.validators import DataRequired, Length


# 為了實作csrf保護,需要設定csrf密鑰,來生成加密令牌
app.config["SECRET_KEY"] = "key string"

# 建立一個表單
form
----------
class DomeForm(Form):
    # 通過字段建立标點,通過驗證器驗證送出資訊的合法性,通過傳參自定義錯誤資訊
    name = StringField("Name", validators=[DataRequired(message='not null')])
    passwd = PasswordField("passwd", validators=[DataRequired(), Length(8, 12)])
    remember = BooleanField('Remember me')
    # 定義送出按鈕
    submit = SubmitField("submit")


# 建立一個視圖函數
methods
------------
@app.route("/basic", methods=["GET", "POST"])
def basic():
    form = DomeForm()
    # if form.validate_on_submit():
    # if request.method == 'POST' and form.validate():
    if request.method == 'POST':
        name = request.form.get('name')
        print(name)
        flash("Hello,%s" % name)
        return redirect(url_for('basic'))
    return render_template('form.html', form=form)


# 編寫一個html頁面
form.html
-------------
{% extends "base.html" %}
{% block title %} Forms {% endblock %}
{% block page_content %}
<form method="post">
    {{form.csrf_token}}
    <!--  bootstrap 表單渲染  -->
    <div class="form-group">
        {{form.name.label}}
        {{form.name(class_='form-control')}}<br>
        # 擷取flash中資料
        {% for message in get_flashed_messages() %}
            <small class="error"> {{message}}</small><br>
        {% endfor %}
    </div>
    {{form.passwd.label}}{{form.passwd}}<br>
    {{form.remember}}{{form.remember.label}}<br>
    {{form.submit}}

</form>
{% endblock %}
           

表單常用字段

python -flask簡介

表單執行個體化參數

python -flask簡介
python -flask簡介

表單常用驗證器

python -flask簡介
python -flask簡介

藍本

# 建立一個藍圖

from flask import Blueprint

admin = Blueprint('admin', __name__)


@admin.route("/")
def index():
    return "admin"


# 注冊藍圖,url_prefix指定藍圖字首

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

工廠函數

# 借助工廠函數可是使部署和測試更加友善

import os
from flask import Flask
from bluelog.setting import config
from bluelog.blueprints.admin import admin
from bluelog.blueprints.blog import blog
from bluelog.blueprints.auth import auth

# 建立工廠函數,flask run時會自動從環境變量FLASK_APP值定義的子產品中找create_app或make_app的工廠函數,自動調用運作,
def create_app(config_name=None):
    # 設定配置
    if config_name is None:
        config_name = os.getenv('FLASK_CONFIG', 'development')
    app = Flask("bluelog")
    app.config.from_object(config[config_name])

    app.register_blueprint(admin, url_prefix='/admin')
    app.register_blueprint(blog, url_prefix='/blog')
    app.register_blueprint(auth, url_prefix='/auth')
    print(app.url_map)
    return app
           

python-dotenv

# 安裝
pipenv install python-dotenv

# 我們可以把所有用到的環境變量寫到.env檔案裡,然後以k,v的方式讀取作為環境變量。
# 最簡單和最常見的用法是目前目錄或其父目錄中的.env檔案或.flaskenv加載環境變量,然後你可以調用os.getenv提供的與環境相關的方法。

.flaskenv
---------
FLASK_APP=bluelog
FLASK_ENV=development
FLASK_CONFIG=development


__init__.py
---------
config_name = os.getenv('FLASK_CONFIG', 'development')
           

jsonify

# 引入
from flask import jsonify

import json

# 使用
@app.route("/tojson")
def test_json():
    rest = {
        "name": "python",
        "age": 24
    }

    # 将python字典轉為json字元串
    json_str = json.dumps(rest)

    # 将json 轉為字典
    rest = json.loads(json_str)

    # flask提供的函數用于字元串轉json
    return jsonify(rest)
           

cookie

# 引入
from flask import make_response, request

# 使用
@app.route('/set_cookie')
def set_cookie():
    resp = make_response("hello")
    resp.set_cookie("dome", "python")

    # 設定有效期,max_age機關秒
    resp.set_cookie("dome2", "python2", max_age=60)
    return resp


@app.route("/get_cookie")
def get_cookie():
    rest = request.cookies.get("dome")
    return rest


@app.route("/del_cookie")
def del_cookie():
    resp = make_response("del")
    resp.delete_cookie("dome")
    return resp
           

session

# 引入
from  flask import session

# 使用
# 配置密鑰
app.config["SECRET_KEY"] = "key string"


# 設定session
@app.route("/set_session")
def set_session():
    session["name"] = "python"
    return "success"


# 擷取session
@app.route("/get_session")
def get_session():
    print(session.get("name"))
    return "index"


# cookie 是加密的session
# cookie 存放在用戶端
# session 存放在伺服器
           

click

Python 内置了一個标準庫用于建立指令行

# 引入
import click
# 建立一個指令


# 添加裝飾器,建立一個指令
@app.cli.command()
# 配置指令參數,
# 指定指令行參數,多參數配置多條選擇,is_flag設定第一個參數的類型為布爾類型,default設定參數的預設值,help 設定參數的幫助資訊。
@click.option('--drop', is_flag=True, help='Create After Drop')
def initdb(drop):
    if drop:
        db.drop_all()
        click.echo("Dorp tables")
    db.create_all()
    click.echo("Create tables")


# 使用
# 不帶參數
flask initdb
# 帶參數
flask initdb --drop