Flask學習筆記:javascript
GitHub上面的Flask實踐項目css
https://github.com/SilentCC/FlaskWeb
html
1.Application and Request Context(上下文)前端
在Flask 中,通常一個view function(視圖函數)會處理一個請求
Flask 中提供request context.保證全局只有一個線程的request,而不會同時出現兩個request.
Application and Request Context 一共有四種
current_app (Application context)
g (Application context)
request (Request context)
session (Request context)
2.Request Dispatching(請求發送)
當服務器接受一個請求,Flask經過創建一個URL mapping ,爲請求找到相應的視圖函數。
Flast 利用 app.route 創建這個Map.
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])
其中 /static/<filename> route 是Flask中特有的。
3.Request Hooks(請求掛鉤)
在接受請求或者處理完請求以後,都要執行一段代碼。好比請求發送以前,咱們須要鏈接一下數據庫。因此
咱們能夠寫一個鏈接數據庫的通用函數。Flask 中Request hook function 提供了這個功能
有四種hook 函數
before_first_request: 當接受第一個請求以前要執行的代碼。
before_request :接受每個請求以前要執行的代碼。
after_request:處理完每個請求以後要執行的代碼,只有請求成功處理以後。
teardown_request:處理完每個請求以後要執行的代碼,請求處理失敗以後也能夠執行的。
在 request hook function 和view function 之間的數據共享是經過全局的g context來完成的。
例如登陸以前,經過before_request請求鏈接數據庫的獲取用戶的信息 g.username。而後在
view function 中就能夠調用g.username
4.Responses(迴應)
每一個view function 都會返回一個value。能夠返回html 頁面。
可是http 協議要求咱們還須要返回一個狀態,好比200 就是成功執行請求,400 就是執行請求發生錯誤。
for example
app.route('/')
def index():
return '<h1>error request<h1>,400'
view function 能夠返回兩個,也能夠返回三個(value,status,headers)
Flask 也提供了專門一個函數make_response()
@app.route('/')
def index2():
response=make_response('<h1>This document carries a cookie!</h1>')
response.set_cookie('answer','42')
return response
除此以外,還有兩種response方式:
redirect(重定向) 實際上一個返回三個的response
from flask import redirect
@app.route('/')
def index():
return redirect('http://www.example.com')
abort(用於拋出錯誤)
from flask import abort
@app.route('/user/<id>')
def get_user(id):
user = load_user(id)
if not user:
abort(404)
return '<h1>Hello, %s</h1>' % user.name
5.Extensions
Command-LineOptions with Flask-Script
Flask 具備可擴展性,能夠下載不少插件。
好比Flask-script 這個插件,就是可讓Flask使用命令行在後臺。
舉個列子:
首先下載Flask_script: $ pip install flask-script
要使用Command-LineOptions這個插件,那麼hello.py就要作相應的改變。
而後咱們在hello.py中能夠這麼寫:
#!/bin/python
from flask import Flask,make_response
from flask.ext.script import Manager
app = Flask(__name__)
manager = Manager(app)
#...
if __name__ =='__main__':
manager.run()
這個時候在終端,咱們就能夠用命令。
$ python hello.py
usage: hello.py [-?] {shell,runserver} ...
positional arguments:
{shell,runserver}
shell Runs a Python shell inside Flask application context.
runserver Runs the Flask development server i.e. app.run()
其中shell 命令是啓動application 中的context的session 前面提到過。
runserver命令是啓動Web server的。
在runserver命令中咱們能夠查看不少命令,$ python hello.py runserver --help
其中有-h,-t,--host,-p,--post 等等
--host能夠設置服務器監聽的網絡地址。--host 0.0.0.0 全部的地址均可以訪問服務器。
6.Jinja2 模板引擎。
首先咱們理解Jinja2 模板引擎是個什麼東西。其實Jinja 模板引擎就是在html的基礎上,在須要交互
數據的地方作一些標註,能實現先後端數據交互。這樣就省了不少前端傳到後端的代碼,實現先後端的MVC
,方便開發。Flask 使用Jinja2模板引擎。
Jinja2 模板引擎之 變量
打印變量用{{ Varibles }}
例如:{{ list[0] }} 打印list數組裏的第一個元素。
變量的過濾器,咱們能夠在變量後面加一個過濾器,對變量進行操做.過濾器和變量用|分隔。
例如:{{ name|capitalize}} 把name這個變量的首字母大寫。
下面介紹幾個過濾器:
Filter name Description
safe Renders the value without applying escaping
capitalize Converts the first character of the value to uppercase and the rest to lowercase Converts the value to lowercase characters
lower ase Converts the value to lowercase characters
upper Converts the value to uppercase characters
title Capitalizes each word in the value
trim Removes leading and trailing whitespace from the value
striptags Removes any HTML tags from the value before rendering
其中safe 過濾器的做用是關閉html轉義。還有escapes過濾器是html轉義。好比一個字符串 s='<h1>hello world</h1>'
{{s|escapes}} 則是將這個字符串轉移成html的內容,從而顯示<h1>標籤的hello world。
若是{{s|safe}} 那就是打印<h1>hello world<h1>
執行語句 用{% %}
if條件
{% if user %}
Hello,{{ user }}!
{% else %}
Hello,Stranger!
{% endif %}
for循環
<ul>
{% for comment int comments %}
<li>{{comment}}</li>
{% endfor %}
</ul>
宏定義 macro
{% macro render_comment(comment)%}
<li>{{comment}}</li>
{% endmacro %}
<ul>
{% for comment in comments %}
{{ render_comment(comment) }}
{% endfor %}
</ul>
宏定義 macro 還能夠導入文件,例如將上面的
{% macro render_comment(comment)%}
<li>{{comment}}</li>
{% endmacro %}
放到macros.html裏面,再經過導入的方式使用宏定義
{% import 'macros.html' as macros %}
<ul>
{% for comment in comments %}
{{ macros.render_comment(comment) }}
{% endfor %}
</ul>
若是有多處須要用到重複的代碼塊,能夠統一到一個文件裏,經過include
{% include 'common.html' %}
flask還有一個很重要的用法就是繼承性。咱們能夠寫一個模板網頁base.html
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %} - My Application</title> {% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
咱們再寫一個base2.html來繼承base.html
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style>
</style>
{% endblock %}
{% block body %} <h1>Hello, World!</h1> {% endblock %}
這裏extends就是繼承的標誌,
block標籤:被block標記的代碼塊,是能夠被改變的
在子頁面中,能夠新建一個block,也能夠對父頁面中的block進行重寫
super()則是繼承父頁面中的block中的已有的代碼
7.Bootstrap
Flask中也可使用boostrap,Flask提供了Flask-Bootstrap 擴展包,用來將
使用bootstrap
$ pip install flask-bootstrap 安裝flask-bootstrap
from flask.ext.bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app) 初始化flask-bootstrap。
8.連接
網頁中有不少須要經過url跳轉到其餘頁面的地方,若是是一個固定的URL,就會很簡單,可是若是是一個動態的URL
好比帶參數的URL,就會比較麻煩。Flask提供了url_for()函數,來統一管理這些URL
url_for最簡單的用法,以hello.py中的視圖函數名爲參數,則會返回這個視圖函數的URL
例如:
視圖函數:
@app.route('/user/<name>')
def user(name):
return render_template('user.html',name=name)
url_for('user', name='john', _external=True)則會返回
http://localhost:5000/user/john.
url_for也能夠不用視圖函數裏的參數,用本身定義的例如:
url_for('index', page=2) 會返回 /?page=2.
url_for也能夠引用不少固定文件,好比css文件,javascript文件,圖片等等
這些固定文件,通常都放在static文件夾下
url_for('static', filename='css/styles.css', _external=True)
會返回 http://localhost:5000/static/css/styles.css.
9.日期和時間
Flask提供了flask-moment,依賴於javascript中的jquery.js和moment.js
提供了對時間和日期處理的各類函數
$ pip install flask-moment 安裝flask-moment
初始化moment
from flask.ext.moment import Moment
moment = Moment(app)
在網頁中導入moment.js
{% block scripts %}
{{ moment.include_moment() }}
{% endblock %}
10.表格
在Flask中使用表格,Flask提供了flask-wtf
$ pip install flask-wtf 安裝flask-wtf
flask-wtf 保護網站的避免受到CSRF攻擊,所謂CSRF攻擊,就是用戶在瀏覽一個網站的時候,得到該網站的
安全驗證,此時在這個網頁中點擊了另外一個惡意網站,惡意網站就能夠得到用戶的信息,操控用戶作一些用戶不想作的事情
在hello.py中加入密鑰,防止CSRG
pp = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
SECRET_KEY是密鑰,配置密鑰的字符串本身能夠設置一個,至關於密碼
使用表格的時候,flask是將表格在hello.py做爲一個類,而後前端再調取這個form Classes
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField from wtforms.validators import Required
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
前端界面:
<form method="POST">
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
</form>
用flask-wtf和flask-bootstrap得到一個表格
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
</div>
{{ wtf.quick_form(form) }}
{% endblock %}
bootstrap/wtf.html 定義了函數,提供用Bootstrap的Flask-WTF
11.session
用法和jsp的session相似
from flask import session
12.flash
若是要在網頁中彈出提示框,Flask提供了flash
from flask import flash
flash('error')
相應的在前端界面:
{{ get_flashed_messages() }}顯示flash裏面的內容
若是有不少條flash須要顯示
就能夠用for循環
{% for message in get_flashed_messages() %}
{{ get_flashed_messages() }}
{% endfor %}
14.整合python shell
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role) manager.add_command("shell", Shell(make_context=make_shell_context))
maker_shell_context()函數,註冊了程序和數據庫,已經實體,而後就能夠控制檯使用shell命令使用
$ python hello.py shell
>>> app
<Flask 'app'>
>>> db
<SQLAlchemy engine='sqlite:////home/flask/flasky/data.sqlite'> >>> User
<class 'app.User'>
13.數據庫
14.Mailjava