2019-03-26 Flask大綱

flask

環(huán)境

使用virtualenv創(chuàng)建

  • 安裝:pip install virtualenv

  • 創(chuàng)建虛擬環(huán)境:virtualenv --no-site-packages -p python.exe的絕對路徑(也可以不寫) 環(huán)境名

  • 激活環(huán)境

    • win:cd 環(huán)境名/Scripts 執(zhí)行activate

    • Linux/Mac:source activate

  • 退出環(huán)境:deactivate

使用pycharm創(chuàng)建

  • 進(jìn)入setting下面的project interpreter頁面,選擇框里面的show all,旁邊有個'+'號,點(diǎn)擊創(chuàng)建虛擬環(huán)境,不繼承全局的包(site-packages)

  • 進(jìn)入setting下面的project interpreter頁面,選擇框里面的show all,旁邊有個'+'號,如果通過dos命令已經(jīng)創(chuàng)建了環(huán)境就選擇Existing enviroment,在本地文件夾中選擇環(huán)境

flask安裝

安裝:先激活環(huán)境,再執(zhí)行pip install flask

pip使用

查詢安裝的庫:pip list / pip freeze

安裝內(nèi)容:pip install xxx

同時安裝多個文件:pip install -r requirement.txt (創(chuàng)建一個requirement.txt文件,在里面編輯要安裝的文件,一個文件占一行)

flask使用

from flask import Flask

創(chuàng)建app對象 app = Flask(name) @app.route('路由地址') def 函數(shù)名(形參列表): 函數(shù)體 return 值

app.run() 在Terminal窗口,虛擬環(huán)境下輸入python 要執(zhí)行的文件名.py

啟動

flask自帶啟動方式:app.run(host='ip地址', port=端口號, debug=True/False)

使用flask-script庫

  • pip install flask-script

  • from flask_script import Manager manager = Manager(app) manager.run()

  • 在Terminal啟動命令:python xxx.py runserver -p -h -d

路由規(guī)則

定義格式:<轉(zhuǎn)換器(類型):參數(shù)名>

轉(zhuǎn)換器

  • int:指定整型

  • string:指定字符串,默認(rèn)類型

  • float:指定浮點(diǎn)類型

注意:string:name和<name>是一樣的

請求與響應(yīng)

請求

  • 獲取參數(shù)

    • GET請求:獲取參數(shù):request.args['key']、request.args.get('key')(推薦 .get的方式)

    • POST請求參數(shù):request.form['key']、request.form.get('key')(推薦 .get的方式)

    • 獲取多個同樣的key對應(yīng)的value時,使用getlist('key')

  • 獲取請求路徑:request.path

  • 請求cookies:request.cookies

  • 獲取上傳文件:request.files 取值:request.files.get('key')、request.files['key']

  • 使用debug?。?!

    • 獲取debug里面request數(shù)據(jù):先按下debug鍵,再在獲取參數(shù)的代碼行標(biāo)紅點(diǎn),載通過postman傳遞參數(shù),這樣就可以操作debug控制臺的Console和Debugger了?。?!

響應(yīng)

  • 導(dǎo)包:from flask import make_response

  • 使用:make_response('響應(yīng)內(nèi)容', 響應(yīng)狀態(tài)碼)

cookie與session

cookie

  • 產(chǎn)生場景:由于HTTP無狀態(tài)協(xié)議,cookie的使用,保存一個令牌(標(biāo)識符)用于標(biāo)識用戶的登錄狀態(tài)

  • 令牌的產(chǎn)生:在登錄時向cookie中設(shè)置的

  • 設(shè)置令牌:res = make_response() res.set_cookie('key', 'value', max_age)

  • cookie不能跨瀏覽器

  • cookie中設(shè)置的參數(shù)有字節(jié)限制,不能無限的存儲參數(shù)

  • 刪除:res = make_response() res.delete_cookie('key')

session

  • flask默認(rèn)存儲session的形式,將session數(shù)據(jù)保存在客戶端

    • 導(dǎo)包:from flask import session

    • 使用:session['key']='value'

  • 使用flask-session庫,將session數(shù)據(jù)保存在服務(wù)器端

    • pip install redis pip install flask-session

    • app.config['SESSION_TYPE'] = 'redis'

    • app.config['SESSION_REDIS'] = redis.Redis(host='', port=6379)

    • 加密復(fù)雜程度,加密,加密復(fù)雜程度和設(shè)值有關(guān) app.secret_key = 'value'

    • from flask_session import Session Session(app)

裝飾器

條件

  • 外層函數(shù)嵌套內(nèi)層函數(shù)

  • 外層函數(shù)返回內(nèi)層函數(shù)

  • 內(nèi)層函數(shù)調(diào)用外層函數(shù)的參數(shù)

注意

  • 外層函數(shù)傳入的參數(shù)即為被裝飾的函數(shù)

  • from functools import wraps @wraps(func)

@function

def test(*args, **kwargs): pass 定義加上裝飾器的函數(shù)的時候,裝飾器就被調(diào)用 這時test = function(test)

藍(lán)圖

產(chǎn)生背景:管理路由地址

安裝:pip install flask-blueprint

使用

  • from flask import Blueprint 第一步:blue = Blueprint('first', name) @blue.route('路由地址')

  • 第二步:flask對象app.register_blueprint(blueprint=blue)

跳轉(zhuǎn)

  • 有參跳轉(zhuǎn)

    • redirect(url_for('生成藍(lán)圖的第一個參數(shù).跳轉(zhuǎn)的函數(shù)名稱', 參數(shù)名=值,參數(shù)名2=值2))
  • 無參跳轉(zhuǎn)

    • redirect(url_for('生成藍(lán)圖的第一個參數(shù).跳轉(zhuǎn)的函數(shù)名稱'))

模板

父模板

  • 定義網(wǎng)站模板的大體框架,可以被動態(tài)填充內(nèi)容的block塊

  • block塊定義: {% block name %} {% endblock %}

  • 注意:block名稱不能取同名

子模板

  • 繼承父模板: {% extends '父模板' %}

  • 動態(tài)可選擇性的填充父模板中定義的block塊,使用{% block name %}動態(tài)內(nèi)容{% endblock %}

語法

  • 解析標(biāo)簽:{% 標(biāo)簽名 %} {% end標(biāo)簽名 %}

    • for:{% for a in [] %} 內(nèi)容 {% else %} 內(nèi)容 {% endfor %}

    • if:[% if 判斷條件 %} 內(nèi)容 {% else %} 內(nèi)容 {% endif %}

    • block:{% block name %} {% endblock %}

  • 解析變量:{{ 變量名 }}

    • loop:變量

      • loop.index0:從0開始

      • loop.revindex:逆序到1結(jié)束

      • loop.revindex0:逆序到0結(jié)束

      • loop.first:第一次循環(huán)返回True

      • loop.last:最后一次循環(huán)返回True

  • 注解:{# 注解內(nèi)容 #}

  • 過濾器

    • 寫法:{{ 變量 | 過濾器 }}

    • safe:轉(zhuǎn)換成對應(yīng)的標(biāo)簽

    • striptags:不解析成標(biāo)簽

    • length

    • upper

    • ......

  • 反向解析路由/地址

    • 解析路由: href="{{ url_for('生成藍(lán)圖的第一個參數(shù).跳轉(zhuǎn)的函數(shù)名稱') }}"

    • 解析地址: <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">

模型

ORM概念:object relationship mapping,對象關(guān)系映射

flask-sqlalchemy庫

  • 安裝:pip install flask-sqlalchemy

  • 創(chuàng)建模型

    """==========zhuming=========="""

    from flask_sqlalchemy import SQLAlchemy

    生成SQLAlchemy數(shù)據(jù)庫訪問對象db

    db = SQLAlchemy()

    繼承了db.Model的類就是一個表

    class Student(db.Model): # 定義id主鍵,自增字段 id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 定義不能為空且唯一的姓名字段 s_name = db.Column(db.String(10), unique=True, nullable=False) # 定義整型,默認(rèn)為20的年齡字段 age = db.Column(db.Integer, default=20)

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n240" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">tablename = 'stu'
    ?
    def save(self):

    保存與修改

    db.session.add(self)
    db.session.commit()
    ?
    def delete(self):

    刪除

    db.session.delete(self)
    db.session.commit()</pre>

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n242" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">#去了解一下

    def init(self):

    pass

    def new(cls, *args, **kwargs):

    pass

    def del(self):

    pass</pre>

    class Teacher(db.Model): tea_id = db.Column(db.Integer, primary_key=True, autoincrement=True) tea_name = db.Column(db.String(10), unique=True, nullable=False) tea_age = db.Column(db.Integer, default=22)

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n244" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">tablename = 'teacher'</pre>

  • 配置數(shù)據(jù)庫信息

  • 映射

    • 創(chuàng)建:sqlalchemy對象db.create_all()

    • 刪除:sqlalchemy對象db.drop_all()

  • db.session.add(對象) db.session.commit()

  • db.session.delete(對象) db.session.commit()

  • db.session.add(對象) db.session.commit()

1、模型名.query就是先從數(shù)據(jù)庫中取到所有數(shù)據(jù) 2、模型名.query.first(),返回所有數(shù)據(jù)中的第一條 3、模型名.query.all(),返回所有數(shù)據(jù) 4、模型名.query.filter().all(),就是從數(shù)據(jù)庫中取到所有數(shù)據(jù)之后,通過filter條件進(jìn)行過濾(篩選),然后把過濾過后的所有數(shù)據(jù)返回

注意:所以要理清query和filter()過濾器在查詢數(shù)據(jù)中扮演的角色,然后就可以靈活運(yùn)用了,這個很重要!?。?/p>

  • query:管理器

  • 模型名.query.filter(模型名.字段 == 值)

  • 模型名.query.filter_by(字段 = 值)

  • 模型名.query.first():查詢結(jié)果中的第一個數(shù)據(jù)對象

  • 模型名.query.all():查詢結(jié)果中的所有對象,返回列表

  • 模型名.query.get():查詢主鍵所在行的對象信息

  • order_by():排序 和filter()的位置可以靈活處理

    • sqlalchemy 1.3版本之前寫法

      • 升序:order_by('字段')

      • 降序:order_by('-字段')

    • sqlalchemy 1.3版本

      • 升序:order_by(模型名.字段)

      • 降序:order_by(-模型名.字段)

  • offset/limit:分頁 和切片分頁

    • 模型名.query.offset((page-1)*N).limit(N).all()

    • 數(shù)據(jù) = 模型名.query.all() 數(shù)據(jù)[(page-1)N : pageN]

  • 模糊查詢

    • 模型名.query.filter(模型.字段.contains('值')).all()

    • like % _

      • 模型名.query.filter(模型名.字段.like('%值_')).all()
    • startswith

      • 模型名.query.filter(模型名.字段.startswith('值')).all()
    • endswith

      • 模型名.query.filter(模型名.字段.endswith('值')).all()
  • in/notin

    • 模型名.query.filter(模型名.字段.in([值1, 值2, ...])).all() 模型名.query.filter(模型名.字段.notin([值1, 值2, ...])).all()
  • 大于:gt 大于等于:ge

    • 模型名.query.filter(模型名.字段.gt(值)).all() 模型名.query.filter(模型名.字段 > 值).all()
  • 小于:lt 小于等于:le

  • and、or、not_

    • from sqlalchemy import and, or, not_ 模型名.query.filter(and_(多個條件用逗號隔開)).all()

    • 條件并列可以直接: 模型名.query.filter(條件1,條件2,...).all()

關(guān)聯(lián)關(guān)系

一對多

  • 定義:

    class Grade(db.Model): # 自增的主鍵id id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 定義不能為空,且唯一的班級名稱字段 g_name = db.Column(db.String(10), nullable=False, unique=True) stus = db.relationship('Student', backref='p', lazy=True)

    繼承了db.Model的類就是一個模型(對應(yīng)數(shù)據(jù)庫的表)

    class Student(db.Model): # 定義id主鍵,自增字段 id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 定義不能為空且唯一的姓名字段 s_name = db.Column(db.String(10), unique=True, nullable=False) # 定義整型,默認(rèn)為20的年齡字段 age = db.Column(db.Integer, default=20) # 定義的關(guān)聯(lián)班級表id的外鍵g_id g_id = db.Column(db.Integer, db.ForeignKey('grade.id'), nullable=True)

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n359" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">tablename = 'stu'</pre>

  • 重點(diǎn)在班級表中關(guān)聯(lián)關(guān)系的定義: stus = db.relationship('Student', backref='p', lazy=True)

  • 班級查詢學(xué)生:班級對象.stus

  • 學(xué)生查詢班級:學(xué)生對象.backref

多對多

  • 定義:

    class Student(db.Model): # 定義id主鍵,自增字段 id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 定義不能為空且唯一的姓名字段 s_name = db.Column(db.String(10), unique=True, nullable=False) # 定義整型,默認(rèn)為20的年齡字段 age = db.Column(db.Integer, default=20) # 定義的關(guān)聯(lián)班級表id的外鍵g_id g_id = db.Column(db.Integer, db.ForeignKey('grade.id'), nullable=True)

class Student(db.Model):
# 定義id主鍵,自增字段
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 定義不能為空且唯一的姓名字段
s_name = db.Column(db.String(10), unique=True, nullable=False)
# 定義整型,默認(rèn)為20的年齡字段
age = db.Column(db.Integer, default=20)
# 定義的關(guān)聯(lián)班級表id的外鍵g_id
g_id = db.Column(db.Integer, db.ForeignKey('grade.id'), nullable=True)
tablename = 'stu'
def save(self):
# 保存與修改
db.session.add(self)
db.session.commit()
?
def delete(self):
# 刪除
db.session.delete(self)
db.session.commit()

c_s = db.Table('c_s',  db.Column('s_id', db.Integer, db.ForeignKey('stu.id')),  db.Column('c_id', db.Integer, db.ForeignKey('course.id'))  )

class Course(db.Model):  id = db.Column(db.Integer, primary_key=True, autoincrement=True)  c_name = db.Column(db.String(10), nullable=False, unique=True)  # 關(guān)系中的lazy參數(shù)值dynamic,通過班級對象.stus的方法獲取學(xué)生對象的時候,是返回  查詢對象,可以進(jìn)行filter()過濾和all()或者first()取值  stus = db.relationship('Student', secondary=c_s, backref='cou', lazy='dynamic')
  • 多對多可以任意選擇一個表添加關(guān)聯(lián)關(guān)系: stus = db.relationship('Student', secondary=c_s, backref='cou', lazy=True)

  • 學(xué)生查詢課程:學(xué)生對象.backref

  • 課程查詢學(xué)生:課程對象.stus

  • 添加和刪除:append/remove

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容