Flask URL和檢視(一)

weixin_34194087發表於2018-06-13

第一個flask程式

from flask import Flask
#建立一個Flask物件,傳遞__name__引數進去
app = Flask(__name__)

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


if __name__ == '__main__':
    app.run()   #flask中的一個測試應用伺服器

debug模式

作用:

如果丟擲異常,在瀏覽器中可以看到具體錯誤資訊
在修改程式碼後,只要按“ctrl+s”,就會自動重啟專案,不用手動重新執行

四種配置方式

第一種

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

第二種

app.debug = True

第三種

app.config.update(DEBUG=True)

第四種

新建config.py

DEBUG = Ture

然後在主程式總匯入引用

import config

app.config.from_object(config)   

配置檔案

新建config.py

DEBUG =True

主程式中兩種引用方式

第一種:

import config

app.config.from_object(config)  

第二種

app.config.from_pyfile('config.py')

url傳參方式

普通傳參方式

@app.route('/p/<id>/')
def article_detail(id):
    return '你訪問的文章第%s篇'%id

指定引數型別

有以下幾種型別:

string:預設的資料型別
int:接受整形
float:浮點型
path:和string的類似,但是接受斜槓
any:可以指定多個路徑
uuid:只接受uuid字串

(1)any

@app.route('/<any(blog,user):url_path>/<id>')
def detail(url_path,id):
    if url_path == 'blog':
        return '部落格詳情%s'%id
    else:
        return '使用者詳情%s'%id

(2)path

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

獲取引數

from flask import Flask,request

@app.route('/tieba/')
def tieba():
    wd = request.args.get('wd')
    return '獲取的引數的是%s'%wd

url_for的使用

(1)通過檢視函式解析出url


from flask import Flask,url_for

@app.route('/')
def hello_world():
    return url_for('my_list',page=2)   #url_for裡面:第一個是檢視函式,第二個是url需要的引數

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

(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'

Response

檢視函式中可以返回的型別

可以返回字串,返回的字串其實底層將這個字串包裝成了一個‘Response’物件
可以返回元組,形式(響應體,狀態碼,頭部資訊),返回的元組其實底層將這個字串包裝成了一個‘Response’物件
可以返回Response及其子類

實現一個自定義的Response物件

繼承自、‘Response’類
實現方法‘force_type’
指定‘app.response_class’為你自定義的‘Response’物件
如果檢視函式返回的資料,不是字串,也不是元組,也不是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)

因為/list3/返回的是字典型別,非字元、非元祖、非Response物件,所以執行force_type方法


12206509-731e615ee0340e65.png
image.png

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()

類檢視

之前使用的檢視都是函式,簡稱為檢視函式,檢視也可以基於類來實現,類檢視的好處是支援繼承,類檢視需要通過app.add_url_role(url_rule,view_func)來進行註冊,類裡面要加裝飾器就用:detactors=[] ,裡面可以新增多個裝飾器

(1)標準檢視

  • 繼承views.VIew
  • 必須實現‘dispatch_request’方法,以後請求過來後,都會執行這個方法,返回值相當於檢視函式一樣,必須返回'Response'或者子類的物件,或者是字串,或者是元祖
  • 必須通過app.add_url_role(url_rule,view_func)來做url與檢視的對映

例項

from flask import Flask,url_for,views

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'))


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

with app.test_request_context():
    print(url_for('list'))    #/list/

if __name__ == '__main__':
    app.run()
12206509-e81fc19f91a50593.png
image

(2)通過類的繼承實現多個檢視返回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()
12206509-734c486538e369ef.png

(3)基於排程方法的類檢視

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'))

相關文章