2010-09-10 79 views
21

我正在使用基於Werkzeug的Flask微框架,該框架使用Python。燒瓶/ Werkzeug,登錄後如何返回上一頁

每個受限頁面之前有一個裝飾,以確保用戶登錄,目前他們返回到登錄頁面,如果他們還沒有登錄,就像這樣:

# Decorator 
def logged_in(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     try: 
      if not session['logged_in']: 
       flash('Please log in first...', 'error') 
       return redirect(url_for('login')) 
      else: 
       return f(*args, **kwargs) 
     except KeyError: 
      flash('Please log in first...', 'error') 
      return redirect(url_for('login')) 
    return decorated_function 


# Login function 
@app.route('/', methods=['GET', 'POST']) 
def login(): 
    """Login page.""" 
    if request.method=='POST': 
    ### Checks database, etc. ### 
    return render_template('login.jinja2') 


# Example 'restricted' page 
@app.route('/download_file') 
@logged_in 
def download_file(): 
    """Function used to send files for download to user.""" 
    fileid = request.args.get('id', 0) 
    ### ... ### 

登錄後,它需要將用戶返回到將他們帶到登錄頁面的頁面。 它還需要保留東西,如傳遞的變量(即整個鏈接基本上www.example.com/download_file?id=3)

有誰知道如何做到這一點?

謝謝您的幫助:-)

回答

20

我認爲標準的做法是將追加到該用戶需要登錄成功登錄URL的查詢字符串結束後重定向的URL。

你會你的裝飾改變這樣的事情(與冗餘在你的裝飾功能也被刪除):

def logged_in(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     if session.get('logged_in') is not None: 
      return f(*args, **kwargs) 
     else: 
      flash('Please log in first...', 'error') 
      next_url = get_current_url() # However you do this in Flask 
      login_url = '%s?next=%s' % (url_for('login'), next_url) 
      return redirect(login_url) 
    return decorated_function 

你需要替換的東西get_current_url(),因爲我不知道怎麼說的嗎在Flask中完成。

然後,在您的登錄處理程序中,當用戶成功登錄時,檢查請求中是否有next參數,如果是,則將其重定向到該URL。否則,你將它們重定向到一些默認的URL(通常我認爲/)。

+1

+1另請參閱第一個鏈接,以獲得方便的小功能燒瓶,以做到這一點 – unmounted 2010-09-11 07:53:35

+8

get_current_url()is flask.request.url – 2011-09-23 14:18:29

11

你可以使用一個查詢字符串來保持文件信息完整的一個或兩個點擊。 url_for的好處之一是它如何passes unknown parameters as query strings。因此,沒有太多改變你的註冊頁面,你可以做這樣的事情:

def login_required(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     if g.user is None: 
      return redirect(url_for('register', wantsurl = request.path)) 
     return f(*args, **kwargs) 
    return decorated_function 

這裏wantsurl將跟蹤用戶登陸的url。如果未註冊的用戶進入/download/some/file.txtlogin_required會送你到/register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt然後你幾行添加到您的註冊功能:

@app.route('/register', methods=['GET', 'POST']) 
def register(): 
    if request.method == 'GET': 
     if 'wantsurl' in request.args: 
      qs = request.args['wantsurl'] 
      return render_template('register.html', wantsurl=qs) 
    if request.method == 'POST': 
     if 'wantsurl' in request.form and everything_else_ok: 
      return redirect(request.form['wantsurl']) 

這將自動重定向到下載上註冊成功,只要你有什麼東西在表單名爲'wantsurl',值爲qs,或者您可以使用查詢字符串提交表單;這可能只是在模板中的其他部分。