flask綜合整理1

前言:

框架的對比css

       Django:1個重武器,包含了web開發中經常使用的功能、組件的框架;(ORM、Session、Form、Admin、分頁、中間件、信號、緩存、ContenType....);html

  Tornado:2大特性就是異步非阻塞、原生支持WebSocket協議;python

  Flask:封裝功能不及Django完善,性能不及Tornado,可是Flask的第三方開源組件比豐富;http://flask.pocoo.org/extensions/web

  Bottle:比較簡單;正則表達式

 

總結:json

  不論優劣,不一樣的工具而已;flask

  小型web應用設計的功能點很少使用Flask;緩存

  大型web應用設計的功能點比較多使用的組件也會比較多,使用Django(自帶功能多不用去找插件);cookie

  若是追求性能能夠考慮Tornado;app

 

Flask的socket是基於Werkzeug 實現的,模板語言依賴jinja2模板,在使用Flask以前須要安裝一下;

pip3 install flask #安裝flask

Flask簡單使用

from flask import Flask,response

app=Flask(__name__) #建立1個Flask實例

@app.route('/')      #路由系統生成 視圖對應url,
def first_flask():    #視圖函數
    return 'Hello World'  #response


if __name__ == '__main__':
    app.run()              #啓動socket

1、flask的配置文件

app=Flask(__name__,template_folder='templates',static_url_path='/static/',static_path='/lizhiqiang')
#模板路徑: template_folder='templates'

#靜態文件路徑:static_url_path='/static/'

#靜態文件引入別名:static_path='/zhanggen'

#設置爲調試環境:app.debug=True (代碼修改自動更新)

#設置json編碼格式 若是爲False 就不使用ascii編碼:app.config['JSON_AS_ASCII']=False 

#設置響應頭信息Content-Type   app.config['JSONIFY_MIMETYPE'] ="application/json;charset=utf-8"  (注意 ;charset=utf-8)

2、路由系統

1.動態路由(url傳參)

@app.route('/user/<name>')

from flask import Flask

app=Flask(__name__)

@app.route('/<name>')  #設置url傳參數 http://127.0.0.1:5000/zhanggen
def first_flask(name):  #視圖必須有對應接收參數
    print(name)
    return 'Hello World'  #response


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

接收字符串類型參數

@app.route('/post/<int:age>')

#接收整型數字參數
app=Flask(__name__)
@app.route('/<int:age>/')  #設置url傳參數 http://127.0.0.1:5000/18/
def first_flask(age):  #視圖必須有對應接收參數
    print(age)
    return 'Hello World'  #response

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

接收整型數字參數

二、指定容許的請求方法

@app.route('/login', methods=['GET', 'POST']) 

# 指定容許的請求方法
app=Flask(__name__)
@app.route('/<path:url>/',methods=['get']) #只容許get請求
def first_flask(url):
    print(url)
    return 'Hello World'  #response

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

指定容許的請求方法

三、經過別名反向生成url

#反向生成url
from flask import Flask,url_for
app=Flask(__name__)
@app.route('/<path:url>',endpoint='name1')
def first_flask(url):
    print(url_for('name1',url=url)) #若是設置了url參數,url_for(別名,加參數)
    return 'Hello World'

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

url_for()反向生成url

四、擴展路由功能:正則匹配url

from flask import Flask, views, url_for
            from werkzeug.routing import BaseConverter

            app = Flask(import_name=__name__)


            class RegexConverter(BaseConverter):
                """
                自定義URL匹配正則表達式
                """
                def __init__(self, map, regex):
                    super(RegexConverter, self).__init__(map)
                    self.regex = regex

                def to_python(self, value):
                    """
                    路由匹配時,匹配成功後傳遞給視圖函數中參數的值
                    :param value: 
                    :return: 
                    """
                    return int(value)

                def to_url(self, value):
                    """
                    使用url_for反向生成URL時,傳遞的參數通過該方法處理,返回的值用於生成URL中的參數
                    :param value: 
                    :return: 
                    """
                    val = super(RegexConverter, self).to_url(value)
                    return val

            # 添加到flask中
            app.url_map.converters['regex'] = RegexConverter


            @app.route('/index/<regex("\d+"):nid>')
            def index(nid):
                print(url_for('index', nid='888'))
                return 'Index'


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

3、視圖

 

一、給Flask視圖函數加裝飾器

注意若是要給視圖函數加裝飾器增長新功能,一點要加在路由裝飾器下面,纔會被路由裝飾器裝飾,才能生生成url關係;

#給Flask視圖加裝飾器
#一、定義1個裝飾器

def auth(func):
    print('我在上面')
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner


app=Flask(__name__)

@app.route('/',methods=['GET'])
@auth #注意若是要給視圖函數加裝飾器,一點要加在路由裝飾器下面,纔會被路由裝飾器裝飾
def first_flask():
    print('ffff')
    return 'Hello World'

if __name__ == '__main__':
    app.run()
#給Flask視圖加裝飾器
#一、定義1個裝飾器

def auth(func):
    print('我在上面')
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner


app=Flask(__name__)

@app.route('/',methods=['GET'])
@auth #注意若是要給視圖函數加裝飾器,一點要加在路由裝飾器下面,纔會被路由裝飾器裝飾
def first_flask():
    print('ffff')
    return 'Hello World'

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

二、request和response

 a.請求相關信息

request.method: 獲取請求方法

request.json

request.json.get("json_key"):獲取json數據 **較經常使用      

request.argsget('name') :獲取get請求參數   

request.form.get('name') :獲取POST請求參數

request.form.getlist('name_list'):獲取POST請求參數列表(多個)

request.values.get('age') :獲取GET和POST請求攜帶的全部參數(GET/POST通用)

request.cookies.get('name'):獲取cookies信息

request.headers.get('Host'):獲取請求頭相關信息

request.path:獲取用戶訪問的url地址,例如(/,/login/,/ index/);

request.full_path:獲取用戶訪問的完整url地址+參數 例如(/login/?age=18)

request.script_root: 抱歉,暫未理解其含義;

request.url:獲取訪問url地址,例如http://127.0.0.1:5000/?age=18;

request.base_url:獲取訪問url地址,例如 http://127.0.0.1:5000/;

request.url_root

request.host_url

request.host:獲取主機地址

 

request.files:獲取用戶上傳的文件

obj = request.files['the_file_name']

obj.save('/var/www/uploads/' + secure_filename(f.filename))  直接保存

 

 b、響應相關信息

return "字符串" :響應字符串

return render_template('html模板路徑',**{}):響應模板

return redirect('/index.html'):跳轉頁面

3 、Flask之CBV視圖

#CBV視圖
from flask import Flask,url_for,views
#-----------------------------------------------------
app=Flask(__name__)               #裝飾器

def auth(func):
    print('我在上面')
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner
#--------------------------------------------------------
class IndexView(views.MethodView):  #CBV視圖
    methods=['GET']                #容許的http請求方法(改CBV只容許GET方法)
    decorators = [auth,]            #每次請求過來都加auth裝飾器

    def get(self):
        return 'Index.GET'
    def post(self):
        return 'Index.POST'

app.add_url_rule('/index/',view_func=IndexView.as_view(name='name1')) #(name='name1'反向生成url別名


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

5、模板語言

Flask使用的是Jinja2模板,因此其語法和Django無差異(Django的模板語言參考Jinja2)

 

1.引用靜態文件

方式1:別名引入

<link rel="stylesheet" href="/zhanggen/commons.css">

方式2:url_for()方法引入

<link rel="stylesheet" href="{{  url_for('static',filename='commons.css')  }}">

 

2.模板語言引用上下文對象

變量

<h1>{{user_list}}</h1> <!--變量 -->
<h1>{{user_list}}</h1> <!--變量 -->

 

循環、索引取值

<ul>
{% for user in user_list %} <!--循環 -->
<li>{{user}}</li>
{% endfor %}

{{user_list.0}} <!-- 索引取值-->

</ul>

複製代碼
<ul>
{% for user in user_list %}   <!--循環 -->
    <li>{{user}}</li>
{% endfor %}

{{user_list.0}}             <!-- 索引取值-->

</ul>
複製代碼

 

Flask的Jinjia2能夠經過Context 把視圖中的函數傳遞把模板語言中執行,這就是Django中的simple_tag和simple_fifter;

simple_tag(只能傳2個參數,支持for、if)

@app.template_global()   #simple_tag
def foo(arg):
    return '<input type="text">'
@app.template_global()   #simple_tag
def foo(arg):
    return '<input type="text">'
<h1>{{foo(1)|safe}}</h1>                   <!--Flask的模板語言支持simple_tag-->
<h1>{{foo(1)|safe}}</h1>                   <!--Flask的模板語言支持simple_tag-->

 

3.wtform(flask表單驗證插件)

3.1. 安裝

pip install wtforms  #安裝wtfroms插件

 

3.2登陸註冊

from flask import Flask,render_template,request
from wtforms import Form
from wtforms.fields import simple,core
from wtforms import validators

app = Flask(__name__)

#登陸
class LoginFrom(Form):
    username = simple.StringField(
        label='用戶名',
        validators=[
            validators.DataRequired(message='用戶名不能是空'),
            validators.Length(min=3,max=16,message='用戶名必須大於%(min)d且小於%(max)d')

        ],
    )
    password = simple.PasswordField(
        label='密碼',
        validators=[
            validators.DataRequired(message='密碼不能是空'),
            validators.Length(min=3, max=16, message='密碼必須大於%(min)d且小於%(max)d')

        ],
    )

@app.route('/',methods=['GET','POST'])
def login():
    if request.method == 'GET':
        fm = LoginFrom()
        return render_template('login.html',wtf=fm)
    else:
        form = LoginFrom(formdata=request.form)
        if form.validate():
            return "ok"

        else:
            return  render_template('login.html',wtf=form)


#註冊
class RegForm(Form):
    username=simple.StringField(
        label='用戶名',
        validators=[
            validators.DataRequired(message='用戶名不能爲空'),
            validators.Length(min=3,max=16,message='用戶名必須大於%(min)d且小於%(max)d'),
        ]
    )
    password = simple.PasswordField(
        label='密碼',
        validators=[
            validators.DataRequired(message='密碼不能是空'),
            validators.Length(min=3, max=16, message='密碼必須大於%(min)d且小於%(max)d'),
            validators.Email(message='密碼必須符合郵箱規則')
        ],
    )
    repassword= simple.PasswordField(
        label='確認密碼',
        validators=[validators.EqualTo(fieldname='password',message='密碼不一致')]
    )
    gender=core.SelectMultipleField(
        label="愛好",
        validators=[validators.Length(min=2, max=4, message="癖好有問題")],
        coerce=int,
        choices=(
            (1, "fengjie"),
            (2, "luoyufeng"),
            (3, "lixueqin"),
            (4, "wuyifan"),
            (5, "panta")
        ),
        default=(1, 3, 5)
    )

@app.route('/reg',methods=["GET","POST"])
def reg():
    if request.method == "GET":
        fm = LoginFrom()
        return  render_template("reg.html",rf=fm)
    else:
        form = LoginFrom(request.data)
        if form.validate():
            return form.data.get("password")
        else:
            return render_template("reg.html", rf=form)

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

html

#login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="" method="post" novalidate>
  {{ wtf.username.label }}
  {{ wtf.username }}
  <p><h1>{{wtf.username.errors.0}}</h1></p>
  <p>
      {{ wtf.password.label }}
  {{ wtf.password }}
  </p>
  <p><h1>{{wtf.password.errors.0}}</h1></p>
  <input type="submit" value="登陸">
</form>
</body>
</html>



#reg.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="" method="post" novalidate>
  {% for field in rf %}
    <p>{{ field.label }}{{ field }}{{ field.errors.0 }}</p>
  {% endfor %}
  <input type="submit" value="註冊">
</form>
</body>
</html>

3.33.2.wtforms源碼 猜測....

源碼給大家一個連接吧,頭疼

https://www.cnblogs.com/sss4/p/8097653.html

未完待續。。。

相關文章
相關標籤/搜索