flask(一)之路由和視圖

 01-介紹

 Flask 是一個 Python 實現的 Web 開發微框架,同時具備很強的擴展能力。css

02-第一個flask程序

# 初始化

from flask import Flask, url_for, views
app = Flask(__name__)

Flask類的構造函數只有一個必須指定的參數,即應用主模塊或包的名稱。在大多數應用中,Python的__name__變量就是所需的值。html

from flask import Flask

# 建立flask對象,傳遞__name__參數進去
app = Flask(__name__)


# url與視圖映射
@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()  # 也能夠更改端口號 run(port=5500)

03-設置debug模式

from flask import Flask
import config
#建立一個Flask對象,傳遞__name__參數進去
app = Flask(__name__)
# app.debug = True   #第二種
# app.config.update(DEBUG=True)  #第三種
app.config.from_object(config)   #第四種

#url與視圖映射
@app.route('/')
def hello_world():
    print('helloworkl')
    return 'Hello World!'

if __name__ == '__main__':
    # app.run(debug=True)   #第一種
    app.run()

04-配置文件

 新建config.py前端

DEBUG =True

主程序中的兩種引用方式:python

# 第一種:推薦使用
import config
app.config.from_object(config)  

# 第二種:
app.config.from_pyfile('config.py')

05-url傳參方式

from flask import Flask, request

# 建立flask對象,傳遞__name__參數進去
app = Flask(__name__)


# 普通的傳參方式  127.0.0.1:5000/p/1
@app.route('/p/<id>/')
def article_detail(id):
    return '你訪問的文章第%s篇' % id


"""
指定參數類型
有如下幾種類型:
    string:默認的數據類型
    int:接受整形
    float:浮點型
    path:和string的相似,可是接受斜槓
    any:能夠指定多個路徑
    uuid:只接受uuid字符串
"""


# any:  127.0.0.1:5000/blog/id  127.0.0.1:5000/user/id
@app.route('/<any(blog,user):url_path>/<id>')
def detail(url_path, id):
    if url_path == 'blog':
        return '博客詳情%s' % id
    else:
        return '用戶詳情%s' % id


# path:  127.0.0.1:5000/article/python/1/
@app.route('/article/<path:test>/')
def test_article(test):
    return 'test_article:{}'.format(test)


# 獲取參數  127.0.0.1:5000/tieba/?wd=python
@app.route('/tieba/')
def tieba():
    wd = request.args.get('wd')
    return '獲取的參數的是%s' % wd


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

06-url_for:實現建立url,只是生成一個url

若是要生成一個css樣式的靜態文件的url須要使用url_for('static',filename='style.css')來建立相應的url。json

視圖中的url_for:flask

# 1. 經過視圖函數解析出url

from flask import Flask, url_for

@app.route('/')
def hello_world():
    # url_for裏面:第一個是視圖函數,第二個是url須要的參數
    return url_for('my_list',page=2)   

@app.route('/list/<page>/')
def my_list(page):
    return 'my_list'

訪問 127.0.0.1:5000/,結果:/list/2/

# 2. url_for裏面多的參數會當作搜索字符

@app.route('/')
def hello_world():
    return url_for('my_list',page=2,count=2)   

@app.route('/list/<page>/')
def my_list(page):
    return 'my_list'

訪問 127.0.0.1:5000/,結果:/list/2/?count=2

模板中的url_for:服務器

模板中的url_for和視圖函數中的url_for是相似的,也是傳遞視圖函數的名字,也能夠傳遞參數。使用的時候,須要在url_for兩邊加上一個{{ url_for('func_name'),ref='/',id='1'}}cookie

07-Response

視圖函數中能夠返回的類型:
    1. 能夠返回字符串,返回的字符串其實底層將這個字符串包裝成了一個‘Response’對象
    2. 能夠返回元組,形式(響應體,狀態碼,頭部信息),返回的元組其實底層將這個字符串包裝成了一個‘Response’對象
    3. 能夠返回Response及其子類

實現一個自定義的Response對象:
    1.繼承自、‘Response’類
    2. 實現方法‘force_type’
    3. 指定‘app.response_class’爲你自定義的‘Response’對象
    4. 若是視圖函數返回的數據,不是字符串,也不是元組,也不是Response對象,那麼就會將返回值傳給‘force_type’,而後將‘force_type’的返回值返回給前端
from flask import Flask,url_for,Response,jsonify

app = Flask(__name__)

class JsonResponse(Response):

    @classmethod
    def force_type(cls, response, environ=None):
        '''
        這個方法只有視圖函數返回非字符、非元祖、非Response對象纔會調用
        :param response:
        :param environ:
        :return:
        '''
        # 把字典轉換成json
        if isinstance(response,dict):
            # jsonify將字典轉換成json對象,還將該對象包裝成了一個Response對象
            response = jsonify(response)
        return super(JsonResponse, cls).force_type(response,environ)

app.response_class = JsonResponse


@app.route('/')
def hello_world():
    return 'Hello world'

@app.route('/list1/')
def list1():
    return Response('list1')  # 合法對象,直接返回

@app.route('/list3/')
def list3():
    return {'username':'derek','age':18}   # 返回的是非字符、非元祖、非Response對象,因此執行force_type方法

if __name__ == '__main__':

    app.run(debug=True)

08-add_url_rule:

from flask import Flask, render_template, url_for

app = Flask(__name__)
app.config.update({
    'DEBUG':True,
   # 配置自動加載模板文件,調試模式下會自動開啓
'TEMPLATES_AUTO_RELOAD':True }) @app.route('/',endpoint='index') def hello_world(): print(url_for("derek_list")) # 經過endpoint找到對應的url /list/ return render_template('index.html') def my_list(): return "列表頁" # 三個參數 # 1.url # 2.給url起個別名,若是沒有指定endpoint,則默認使用視圖函數的名字做爲endpoint的值 # 3.視圖函數 app.add_url_rule('/list/',endpoint='derek_list',view_func=my_list) with app.test_request_context(): print(url_for('index')) # / if __name__ == '__main__': app.run()

09-render_template: 渲染模板文件

from flask import Flask, render_template, url_for

return render_template('index.html')

10-send_from_directory:主要用於下載文件

from flask import Flask
from flask import g
from flask import send_from_directory
from flask import url_for
import os.path
 
app = Flask(__name__)
dirpath = os.path.join(app.root_path,'upload')
@app.route("/download/<path:filename>")
def downloader(filename):
    return send_from_directory(dirpath,filename,as_attachment=True)

 11-static_url_path和static_folder

 static_url_path主要用於改變url的path的,靜態文件放在static下面,因此正常狀況url是static/filename ,可是能夠經過static_url_path來改變這個url。app

 static_folder主要是用來改變url的目錄的,默認是static,能夠經過這個變量來改變靜態文件目錄。框架

from flask import Flask
from flask import g
from flask import send_from_directory
from flask import url_for
import os.path
 
app = Flask(__name__,static_url_path="/test")
 
@app.route("/")
def static_create():
    return url_for('static',filename='style.css')

12-Request對象

Request是Flask中表示當前請求的request對象,通常稱之爲請求上下文變量(能夠理解成全局變量,在任意一個視圖中均可以訪問到)。經常使用的屬性有:

  args:url中的查詢字符串。本質上是鍵值對,跟在"?"後面,多個鍵值對之間使用"&"鏈接;

  form:請求url中的表單數據。也是由鍵值對組成,通常使用post方法提交數據

  cookies:請求中的cookie信息。由服務器生成的鍵值對,把值發送給客戶端並保存,稍後重點講解!

  files:上傳的文件

12-類視圖

1. 繼承views.VIew。
2. 必須實現‘dispatch_request’方法,之後請求過來後,都會執行這個方法,返回值至關於視圖函數同樣,必須返回'Response'或者子類的對象,或者是字符串,或者是元祖。
3. 必須經過app.add_url_role(url_rule,view_func)來作url與視圖的映射。
from flask import Flask, url_for, views
# 建立一個Flask對象,傳遞__name__參數進去
app = Flask(__name__)

app.config.update({
    'DEBUG': True,
    'TEMPLATES_AUTO_RELOAD': True,
})


class ListView(views.View):
    def dispatch_request(self):
        return "個人列表頁"


# 1.ListView.as_view('list')裏面必須傳個參數‘name’,給view_func起個別名,實際上就是dispatch_request函數
# 2.endpoint也能夠不指定,則默認使用view_func的別名(name參數的值)
app.add_url_rule('/list/', endpoint='list', view_func=ListView.as_view('list'))


# url與視圖映射
@app.route('/')
def hello_world():
    return 'Hello World!'


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

13-經過類的繼承實現多個視圖返回json數據

from flask import Flask,url_for,views,jsonify

app = Flask(__name__)
app.config.update({
    'DEBUG':True,
    'TEMPLATES_AUTO_RELOAD':True
})

# 父類,把數據轉換成json格式
class JsonView(views.View):
    def get_data(self):
        raise NotImplementedError

    def dispatch_request(self):
        return jsonify(self.get_data())

# 子類只須要寫get_data方法
class ListView(JsonView):
    def get_data(self):
        return {"usernmae":'derek','age':18}

app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))


@app.route('/')
def hello_world():
    return 'Hello World!'

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

14-基於調度方法的類視圖

class LoginView(views.MethodView):
    def __render(self,error=None):
        return render_template('login.html', error=error)

    def get(self,error=None):
        return self.__render()

    def post(self):
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'derek' and password == '123':
            return '登陸成功'
        else:
            return self.__render(error='用戶名或密碼錯誤')

app.add_url_rule('/login/',view_func=LoginView.as_view('login'))

 15-路由

方式一:

  在Flask應用中定義路由的最簡單方式,是使用應用實例提供的 app.route 裝飾器。

# url與視圖映射
@app.route('/')
def hello_world():
    return 'Hello World!'

方式二:

  使用 add_url_rule()方法。接收3個參數:URL,端點名和視圖函數。

16-Web開發服務器

Flask應用自帶Web服務器,經過 flask run 命令啓動。這個命令在 FLASK_APP 環境變量指定的python腳本中尋找應用的實例。

$ export FLASK_APP=hello.py

$ flask run

17-請求-響應循環

17.1 應用和請求上下文

爲了不大量無關緊要的參數把視圖函數弄得很亂,Flask使用 上下文 臨時把一些變量變爲全局能夠訪問。

在Flask中有兩種上下文:應用上下文和請求上下文。

注意:獲取應用上下文的方法是應用實例上調用 app.app_context()。

17.2 請求分派

17.3 請求對象

Falsk經過上下文變量request對外開放請求對象,包含了客戶端發送的HTTP請求的所有信息。

Flask請求中最經常使用的屬性和方法:

17.4 請求鉤子

相關文章
相關標籤/搜索