Flask(二)

 

鉤子函數html

from flask  import Flaskpython

app = Flask(__name__)redis

# 第一次請求以前會來調用數據庫

# 初始化操做json

@app.before_first_requestflask

def demo1():api

      print("第一次請求會調用"")瀏覽器

# 每次請求以前都會調用,應用場景:封裝ip處理服務器

@app.before_requestcookie

def demo2():

  print("每次請求以前會被調用")

#每次請求以後都會調用這個鉤子函數,應用場景:對response進行統一處理

@app.after_request

def demo3(response):

  # response.headers["Content-Type"] = "application/json"

  print("每次請求以後纔會調用")

  return response

 

# 每次都會執行,都會帶入一個服務器的錯誤過來

@app.teardown_request

def demo4(err):

  print(err)

  print("每次請求以後都會調用一個服務器錯誤過來)

 

if  __name__ == "_main__":

  app.run(debug=True)

 

 

對cookie進行操做:

from flask import Flask, make_response, request

app = Flask(__name__)

@app.route("/login")

def login():

  """登陸成功以後藉助cookie保存用戶登陸信息"""

  # 建立響應對象

  response = make_response("login_success")

  # 藉助響應對象的set_cookie方法設置鍵值對

  # 參數1:ke, 參數2:value, 參數3:max_age表示過時時長(以秒爲單位)

  # set_cookie("key",值) Cookie是存儲在瀏覽器中的一段純文本

  response.set_cookie("user_name", "kangkang", max_age=3600)

  response.set_cookie("age", "18", max_age= 3600)

  return response

# 獲取cookie

@app.route("/index")

def index():

"""再次請求首頁的時候,提起cookie中的用戶信息"""

  user_name = request.cookies.get("user_name", "")

  age = request.cookies.get("age", "")

  return "index %s --- %s" %(user_name, age)

 

# 刪除cookie

@app.route("/login_out")

def login_out():

  response = make_response("login_out success")

  response.delete_cookie("user_name")

  response.delete_cookie("age")

  #將響應對象返回

  return response

 

if __name__== "__main__":

  app.run(debug=True)

 

對session進行操做,session依賴於cookie,服務器會返回一個session_id即爲cookie,session裏面包含用戶信息

from flask import Flask, session

app = Flask(__name__)

# session須要設置祕鑰,能夠寫一個任意的字符串,兩種寫法,app.config是個字典

app.config="2323242423"

app.config["SECREY_KEY"] = "3213232"

 

@app.route("/login")

def login():

  # session將用戶數據存儲在服務器的內存中--redis數據庫

  session["user_name"]= "kangkang"

  session["user_id"] = "12"

  return "login success"

 

@app.route("/index")

def index():

  user_name = session.get("user_name", "")

  user_id = session.get("user_id", "")

  return "index:%s ---%s" %(user_name, user_id)

 

@app.route("/login_out")

def login_out():

  session.pop("user_name", "")

  session.pop("age", "")

  return "login_out success"

 

if __name__ == "__main__":

  app.run(debug=True)

 

 

捕獲異常:

from flask import Flask, redirect, abort

 

app = Flask(__name__)

 

@app.route("/")

def hello():

  a = 1/0

  abort(404)  # 主動產生一個404異常,abort須要先導入該庫,abort傳入的必須是http存在的錯誤狀態碼

  return "hello world"

 

# 經過errorhandler捕獲錯誤狀態碼

@app.errorhandler(404)

def handler(e):

  print(e)

  # 重定向到百度的錯誤頁面連接

  return redirect("https://www.baidu.com/search/error.html")

# 經過errorhandler捕獲異常

@app.errorhandler(ZeroDivisionError)

def err(err):

  return "不能除以0"

 

if __name__ == "__main__":

  app.run(debug=True)

 

 

上下文:

請求上下文: request和session

應用上下文:current_app, g變量(flask程序全局的一個臨時變量)

from flask import Flask, request, session, current_app, g

 

app =Flask(__name__)

app.config["SECRECT_KEY"] = "avdvdvd"

# print(request.method)  Working outside of request context.請求上下文超出範圍

# print(g.user) Working outside of request context.應用上下文超出範圍

# 只能在視圖函數裏面進行操做,在外部進行操做就會超出範圍

@app.route("/")

def hello():

# 請求上下文

  print(request.method)

  print(request.url)

  session["user_name"] = "curry"

  print(session.get("user_name", ""))

  # 應用上下文(current_app, g)

  print(current_app.config.get("DEBUG"))

  g.user = "james"

  print(g.user)

  return "hello world"

 

if __name__ == "__main__":

  app.run(debug=True)

 

  • 請求上下文:保存了客戶端和服務器交互的數據
  • 應用上下文:flask 應用程序運行過程當中,保存的一些配置信息,好比程序名、數據庫鏈接、應用信息等

 

Flask-Script拓展

須要安裝Flask-Script拓展

pip install flask-script

from flask import Flask

from flask_script import Manager

app = Flask(__name__)

manager= Manager(app)

@app.route("/")

def hello():

  return "hello world"

 

if __name__ == "__main__":

  manager.run()

經過終端命令: python XX.py runserver  -h ip地址 -p 端口號  -d

一樣也能夠配置該文件的環境變量進行右鍵運行.

 

 

Jinja2模板引擎簡介

視圖函數的主要做用是生成請求的響應,這是最簡單的請求。實際上,視圖函數有兩個做用:處理業務邏輯和返回響應內容。在大型應用中,把業務邏輯和表現內容放在一塊兒,會增長代碼的複雜度和維護成本。本節學到的模板,它的做用便是承擔視圖函數的另外一個做用,即返回響應內容。

  • 模板實際上是一個包含響應文本的文件,其中用佔位符(變量)表示動態部分,告訴模板引擎其具體的值須要從使用的數據中獲取
  • 使用真實值替換變量,再返回最終獲得的字符串,這個過程稱爲「渲染」
  • Flask是使用 Jinja2 這個模板引擎來渲染模板

使用模板的好處:

視圖函數只負責業務邏輯和數據處理(業務邏輯方面)

而模板則取到視圖函數的數據結果進行展現(視圖展現方面)

代碼結構清晰,耦合度低

Jinja2:是 Python 下一個被普遍應用的模板引擎,是由Python實現的模板語言,他的設計思想來源於 Django 的模板引擎,並擴展了其語法和一系列強大的功能,其是Flask內置的模板語言。

模板語言:是一種被設計來自動生成文檔的簡單文本格式,在模板語言中,通常都會把一些變量傳給模板,替換模板的特定位置上預先定義好的佔位變量名

Flask提供的 render_template 函數封裝了該模板引擎

render_template 函數的第一個參數是模板的文件名,後面的參數都是鍵值對,表示模板中變量對應的真實值

{{}}來表示變量名,這種{{}}語法叫作代碼塊變量, {{{position.title}}

Jinja2模板中的變量代碼塊能夠是任意Python類型或者對象,只要它可以Python的Str()方法轉換爲一個字符串就能夠,

{{your_dict['key']}}

{{your_list[0]}}

用{% %}定義的控制代碼塊,能夠實現一些語言層次的功能,好比循環或if語句

{% if user %}

  {{user}}

{% else %}

  hello!

<ul>

  {% for index in indexs %}

    <li>{{index}}</li>

    {% endfor %}

</ul>

使用{# #}進行註釋,註釋的內容不會再html中被渲染出來

 

 

模板的基本使用:

在項目下建立templates文件夾,用於存放全部的模板文件,並在目錄下建立一個模板html文件

 

from flask import Flask, render_template

app = Flask(__name__)

 

@app.route("/")

def index():

  myint = 18

  mystr = "curry"

  my_list =[1, 23,4,6,5]

  my_dict = {

  "name":"duan",

  "age":28

  }

  return render_template("dem01.html",

             myint = myint, mystr = mystr, my_dict=my_dict, my_list = my_liust)

 

if __name == "__main__":

  app.run()

 

對應的demo01.html:

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8"> <title>Title</title> </head> <body> 個人模板html內容 <br/>{{ my_str }} <br/>{{ my_int }} <br/>{{ my_array }} <br/>{{ my_dict }}

</body> </html>

 

鏈式調用: {{"hello world" | reverse | upper}}

常見內建過濾器:

字符串操做

safe:禁止轉義 {{"<em>hello</em>"| safe}}

capitalize:把變量的首字母轉成大寫,其他字母小寫 {{'hello" | capitalize}}

lower:把值轉成小寫, {{"HELLO" | lower}}

upper:把值轉成大寫,{{"hello" | upper}}

title:把每一個單詞的首字母都轉成大寫, {{'he is girl" | title}}

reverse:字符串反轉,

format:格式化輸出 {{'%s is %d' | format('name', 7)}}

striptags:把html中的tag去掉, {{'<h1>hello</h1>" | striptags}}

truncate:字符串截斷 {{'hello every one" | truncate(9) }}

列表操做

list=[1,2,3,1,2,3,6,8,4]

first :取第一個元素 {{list | first}}

last:取最後一個元素{{list | last}}

length:獲取列表長度{{list | length}}

sum:求列表的和{{list | sum}}

sort:列表排序 {{list | sort}}

語句塊過濾:

{% filter upper %}

 # 一大堆文字#

{% endfilter %}

 

 

自定義過濾函器

from flask import render_template, Flask

app = Flask(__name__)

# 方法一:自定義列表反函數

@app.template_filter("list_reverse")

def list_rever(list):

  list.reverse()

  return list

# 方式二:將自定義的函數添加到flask過濾器中,add_template_filter(函數名, "建立過濾器名稱") 函數名不須要打引號

app.add_template_filter(list_rever, "list_reverse")

@app.route("/")

def index():

  list = [1,2,3,4,6,5]

  return render_template("demo02.html", list = list)

 

if __name__ == "__main__":

   app.run(debug=True)

 

 

demo02.html內容:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
自定義過濾器<hr>
<body>
{{ list }}
<br>
{{ list | list_reverse }}
</body>
</html>

 

 控制代碼:

from flask import Flask, render_template

app = Flask(__name__)

 

@app.route("/")

def index():

  # 只顯示四行數據, 並設置顏色

  my_list = [

    

{
"id":1,
"value":"我愛代碼"
},
{
"id": 2,
"value": "代碼令人快樂"
},
{
"id": 3,
"value": "沉迷於代碼沒法自拔"
},
{
"id": 4,
"value": "日漸消瘦"
},
{
"id": 5,
"value": "以夢爲馬,越騎越傻"
}

]

return render_template("demo03.html", my_list = my_list)

 

if __name__ == "__main__":

  app.run(debug=True)

 

demo03.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
控制代碼塊<hr>
{% for item in my_list%}
{# {% if item.id != 5 %}#}
{% if loop.index == 1 %}
<li style="background-color: yellow">{{ item.value }}</li>
{% elif loop.index == 2%}
<li style="background-color: #2aabd2">{{ item.value }}</li>
{% elif loop.index == 3 %}
<li style="background-color: #2b542c">{{ item.value }}</li>
{% elif loop.index == 4 %}
<li style="background-color: #8a6d3b">{{ item.value }}</li>
{% elif loop.index == 5 %}
<li style="background-color: darkgrey">{{ item.value }}</li>

{% endif %}

{# {% endif %}#}


{% endfor %}


loop.index: 當前循環迭次的次數(從1開始)

loop.index0:當前循環迭代的次數(從0開始)

loop.revindex: 到循環結束須要迭的次數(從1開始)

loop.revindex0:到循環結束須要迭代的次數(從0開始)

loop.first 第一迭代,爲True

loop.last 最後一次迭代,爲True

loop.length  序列中的項目數

loop.cycle:在一串序列期間取值的輔助函數.

模板繼承:

在模板中,可能會遇到如下狀況:

  • 多個模板具備徹底相同的頂部和底部內容
  • 多個模板中具備相同的模板代碼內容,可是內容中部分值不同
  • 多個模板中具備徹底相同的 html 代碼塊內容

像遇到這種狀況,可使用 JinJa2 模板中的 繼承 來進行實現

from flask import Flask, render_template

app = Flask(__name__)

 

@app.route("/parent")

def parent():

  return render_template("base.html")

 

@app.route("/child")

def child():

  return render_template("child.html")

 

if __name__ == "__main__":

  app.run(debug=True)

 

base.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
{# 把要重寫的父類的內容用{% block 名稱x %} XXX {% endblock %}#}
{% block testA %}
<h2>父類模板<h2>
{% endblock %}
<h2>父類內容</h2>
<h2>父類底部</h2>

<body>

</body>
</html>

child.html內容:

{# 子類繼承父類使用extends關鍵字 {% extends  '父類.html'  %}#}

{% extends "base.html'' %}

{# 重寫父類中的部份內容#}

{# 不丟失父類原有的內容使用super()#}

{% block testA % }

{{super()}}

<h2>我是子類模板</h2>

{% endblock %}

 

 

怎樣設置templates的html文件在使用render_template方法時自動彈出裏面的html文件進行選擇

選擇Jinja2,apply以後點擊ok便可

 

能夠設置本身設置狀態碼及狀態碼解釋

from flask import Flask

app = Flask(__name__)

@app.route("/")

def index():

  # 666表明狀態碼, 解釋爲狀態碼的解釋信息

  return "hello world", "666 解釋"

if __name__ == "__main__":

  app.run(debug=True)

相關文章
相關標籤/搜索