1. 程式人生 > 程式設計 >flask框架url與重定向操作例項詳解

flask框架url與重定向操作例項詳解

本文例項講述了flask框架url與重定向操作。分享給大家供大家參考,具體如下:

1. url與函式的對映

當我們新建一個flask專案的時候,預設就會有一個hello_world函式,如下面這樣

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

上面函式中,app.route()的引數就是我們的url,當我們啟動專案的時候,我們在瀏覽器中輸入127.0.0.1:5000,就能夠訪問到我們這個檢視了,因為/就是代表"根url",所以我們只需要ip地址和埠就訪問到了我們的這個函式檢視。

當我們將app.route()的引數改為'/hello/'時,那我們訪問這個檢視就需要輸入網址為127.0.0.1:5000/hello/才能訪問到我們的這個檢視了,

這就是flask中url與函式的對映。

2. url傳入引數

  1. url中包含引數

當我們訪問CSDN,部落格園,簡書等網站中的文章詳情的時候,我們會發現起始每篇文章的詳情頁面的url前面不封都是一樣的,只有後面一部分不一樣。那麼這個不一樣的部分我們就可以當做一個引數傳入檢視中,然後我們在檢視中拿到相應的引數在進行相應的操作,返回相應的資料。那麼在flask中怎樣實現這個功能呢?

@app.route('/article_detail/<article_id>/')
def article_detail(article_id):
  return "你檢視到文章id 為 %s" % article_id

在上面的函式檢視中,app.route()中用<>這個包裹起來的就是我們定義的引數,這裡我們就定義了一個article_id這樣的引數。當我們在url中定義了一個引數之後,我們必須也在函式中寫入這個引數,而且引數名必須和url中的引數名一致。然後我們就可以在檢視中拿到article_id這個引數的值了。

然後啟動專案,在瀏覽器中輸入127.0.0.1:5000/article_detail/3/等相似 的url,就能夠檢視到相應的效果了。

上面的例子中雖然我們能夠將引數通過url傳入函式檢視中,但是我們並不能對url做型別限制,比如我們想要的article_id必須是一個int資料,當用戶傳入的引數不是int型的資料的時候,那麼他就訪問不到我們這個函式檢視.出現404頁面.那麼flask中怎樣實現這樣這個需求呢?

在flask中,我們是可以對url指定型別的。

@app.route('/article_detail/<int:article_id>/')
def article_detail(article_id):
  return "你檢視到文章id 為 %s" % article_id

這樣,我們就對傳入的引數做了型別限制。只需要引數前面寫上我們的型別就可以了.

在flask中,除了支援int型別外,還支援以下型別:

  • string: 預設的資料型別,接受沒有任何斜槓/的字串。
  • int: 整形
  • float: 浮點型。
  • path: 和string類似,但是可以傳遞斜槓/。
  • uuid: uuid型別的字串。(什麼是uuid?)
  • any:可以指定多種路徑,這個通過一個例子來進行說明:
@app.route('/<any(blog,article):url_path>/<int:id>/')
def detail(url_path,id):
  if url_path == 'blog':
    return 'blog detail is ' + str(id)
  else:
    return 'article detail is ' + str(id)

這樣,我們在瀏覽器中輸入127.0.0.1:5000/blog/3/127.0.0.1:5000/article/3/都能夠訪問到這個檢視,那麼我們怎麼知道當前是以哪個url訪問的呢,我們可以通過:後面我們定義的url_path引數來接受這個值,然後我們在檢視中也要寫入這個引數。然後我們就能拿到這個值了.

  1. url中以查詢字元竄的方式傳遞引數(get請求)

有些時候,我們並不需要向上面那樣傳遞引數,通過?xxx=xxx這樣的形式傳遞引數。

那麼在flask中,我們怎樣得到這種引數的值呢?

from flask import request
@app.route('/search/')
def search():
  name = request.args.get('name')
  return "查詢字串傳入引數 %s" % name

比如在上面的檢視函式中,我想傳入name=xxx,以查詢字元竄的方式(get請求),那麼我們直接在瀏覽器中輸入127.0.0.1:5000/search/?name=xxx,然後我們在函式檢視中通過request.args.get()方法就能夠拿到這個值了。

如果我們url中沒有傳入name這個引數,那麼我們的程式也不會報錯,只會得到一個None,並不會影響我們程式碼的執行。

3. 構造url,url_for的使用

在上面的程式碼中,都是通過在瀏覽器中輸入url,從而找到我們的檢視函式。那麼我們可不可以反過來呢,知道檢視函式,從而得到相應的url。

這個時候我們就需要使用url_for了,首先我們的先匯入。

from flask import url_for
@app.route('/url_for/')
def url_for_demo():
  return 'url_for_demo'
@app.route('/index/')
def index():
  #        函式的名字
  return url_for('url_for_demo')

url_for中引數為函式的名字,如果傳入的函式不存在就會報錯。讓我們在瀏覽器中輸入127.0.0.1:5000/index/的時候,我們就能夠看到url_for_demo這個函式對應的url了。沒有引數的url學會了,那麼如果url中攜帶引數怎麼辦?

在url_for這個函式中,我們也是可以傳入關鍵字引數的,只需要和url中的引數對應上就好了。

@app.route('/article/<int:article_id>/')
def article_detail(article_id):
  return "article id is " + str(article_id)
@app.route('/index/')
def index():
  # 注意 這裡的關鍵字引數的key不是隨便取的,必須的和該函式對應的url中引數名一樣
  url = url_for('article_detail',article_id=2)
  return url

這樣,我們也能在url_for中傳入url的引數了

那麼如果我們在url_for中傳入url中不存在的關鍵字引數,會怎麼樣呢?

@app.route('/article/<int:article_id>/')
def article_detail(article_id):
  return "article id is " + str(article_id)
@app.route('/index/')
def index():
  # 注意 這裡的關鍵字引數的key不是隨便取的,必須的和該函式對應的url中引數名一樣
  url = url_for('article_detail',article_id=2,name='xxx')
  return url

當我們訪問這個url的時候,就會返回這樣的一個url:/article/2/?name=xxx

也就是說,當我們傳入url中沒有的關鍵之引數,url_for就會以查詢字元竄的方式給我們新增到url上。

那麼我們的到函式對應的url有什麼用呢?

url_for一般是和重定向一起使用,一般不會單獨使用,所以接下來我們來講重定向。

4. 重定向

重定向分為永久性重定向與暫時性重定向

  • 永久性重定向:http的狀態碼為301,多用於舊網址廢棄了,需要轉到一個新的網址確保使用者的訪問。比如京東的網站。當我們輸入jingdong.com的時候,瀏覽器會給我們重新跳轉至jd.com這個網頁,因為jingdong.com這個網址已經被廢棄了,所以會給我們重新跳轉至jd.com。這就是永久性重定向。
  • 暫時性重定向:http的狀態碼為302,表示頁面的暫時性跳轉,比如在一個網站中我們直接訪問個人中心頁面,但是因為沒有登陸,所以就會直接給我們跳轉至登陸頁面。

在flask中,使用重定向需要使用到direct這個函式.

我們通過一個小例子來說明重定向的使用。

需求:當我們訪問個人中心的時候,如果沒有登陸,就需要跳轉至登陸頁面,這裡我們假設在url中傳入了name引數,就認為是登陸了。程式碼如下

from flask import redirect,url_for
@app.route('/login/')
def login():
  return 'login'
@app.route('/profile/')
def profile():
  name = request.args.get('name')
  if name:
    return 'profile 頁面'
  else:
    return redirect( url_for('login') )

上面的程式碼就實現了我們的需求。

這個時候可能有人會問,在redirect函式中,我們也可以不使用url_for,直接構造手動構造url啊,也不是特別麻煩的,例如這樣。return redirect('login'),這樣,我也能直接跳轉至login頁面啊。

這裡就大概說一下使用url_for的好處吧:

  • 當我們的專案特別大的時候,如果某一天老闆需要我們修改一下url,例如將/index/修改為/xxx/index/,那麼我們在app.route中修改了之後,如果我們的專案中大量的使用的redirect重定向到我們的這個函式檢視中,那麼我們就必須的去程式碼中一個一個的找出來,然後去修改程式碼,而如果我們使用了url_for,那就不會出現這樣的問題了,直接修改@app.route就行了,而其他地方因為我們使用的是url_for生成的,所以完全不需要我們去修改。
  • 當我們的url中擁有特殊字元的時候,如'/',如果我們直接手動構造這個引數的話,那麼就可能會出現歧義了,這個'/‘是當做url中的'/‘來識別呢還是當做一個普通的字元'/‘來識別呢,所以可能就會出現頁面找不到的情況,而使用url_for的話,url_for就會將'/'編碼,然後我們使用的時候優惠解碼回來,所以就不會出翔上面那種狀況。

5. 指定HTTP請求方法

有些時候,我們的一個檢視只允許POST方法訪問,而@app.route()預設只允許GET方法,那麼我們如何指定允許請求的方法呢?

@app.route()中可以傳入一個關鍵字引數methods來指定本方法支援的HTTP方法

# 只允許POST方法
@app.route('/post_demo/',methods=['POST'])
def post_demo():
  return 'post'
# 預設的就是這種情況,所以當方法為get請求是,我們一般都省略不寫
@app.route('/get_demo/',methods=['GET'])
def get_demo():
  return 'get'
# GET,POST方法都允許
@app.route('/all_demo/',methods=['POST','GET'])
def all_demo():
  return 'all'

注意:

@app.route('/index')@app.route('/index/')起始是對應的兩個url,一般我們在專案中,都是使用後面一種,因為在有些瀏覽器中,當我們最後面沒有加'/'時,瀏覽器會自動給我們新增上去,而我們有沒有這樣的一個url,所以就有可能會造成頁面找不到的情況。所以在專案中,我們一般都會寫成後面那種形式。

希望本文所述對大家基於flask框架的Python程式設計有所幫助。