2012-01-19 39 views
9

我是python和django的新手,我有一個關於重定向功能的問題。Django與kwarg重定向

這是我的views.py文件的簡化版本。

def page_index(request, error_message=''): 
    print error_message 

def add_page(request): 
    return redirect('page_index') # this work fine 
    return redirect('page_index', error_message='test') # this does not work 

這裏是我的urls.py短版

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', {'error_message': 't'}, name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 

當我嘗試重定向沒有關鍵字參數一切正常到PAGE_INDEX,但是當我使用kwag我得到以下錯誤消息:

NoReverseMatch在/頁/添加/

反向與參數 'PAGE_INDEX' '()' 的d關鍵字參數'{'error_message':'test'}'找不到。

我在做什麼錯?

回答

10

簡答:你的url方案中沒有關於'error_message'關鍵字的地方。

較長答案:

重定向()函數是反向調用()來構建URL;它將通過返回帶有302重定向狀態碼的HTTP響應以及新的url來將用戶的瀏覽器發送到該URL。您提供給reverse()的任何關鍵字參數都應該最終成爲url的一部分 - 這就是它們如何傳達給用戶。

就你而言,'page_index`的網址只是定義爲'^ $' - 這是根網址,它在瀏覽器中看起來像'http://yoursite.com/'。

如果您希望能夠發出包含其他信息的重定向,您需要在url中爲它定義一個位置,或者以不同的方式添加它。

兩個 三種方式是很常見的:

  1. 使用查詢參數 - 這將消息發送到客戶端明確;如果你不小心,人們可以製作網址,讓你的索引頁面發表任何他們想要的內容。

    return redirect(reverse('page-index')+"?error_message=test")) 
    
  2. 藏匿在了會議,並拉出下一個頁面加載時的消息 - 這需要你已經配置的會話,並跟蹤所有的在服務器端,而不是依賴於客戶端來送你回去的錯誤消息:

    def add_page(request): 
        request.session['error_message'] = 'test' 
        return redirect('page-index') 
    
    def page_index(request): 
        print request.session.get('error_message','') 
    
  3. 使用的消息框架這一點 - 這是優於臨時會話屬性,只要你並不需要太多的消息的「類型」同一頁。如果你已經是在你的模板錯誤信息的空間,雖然,那麼這是很容易:

    from django.contrib.messages import error 
    
    def add_page(request): 
        error(request, 'test') 
        return redirect('page-index') 
    

    ,然後在基本模板,有這樣的地方(可能比這更復雜的塊;病急亂投醫即使):

    {% for message in messages %} 
        <p>{{ message }}</p> 
    {% endfor %} 
    

兩種 所有的情況下,雖然,你可以從你的urls.py刪除參數 - 消息本身不會成爲的路徑組件的一部分URL。

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 
+0

有沒有辦法來調用帶有信息的觀點,那不是在網址是什麼? – Justus1

+0

是的,你用Python做的 - 只需從你的add_page視圖中返回page_index(error_message ='test')'。 –

+1

但如果你這樣做,那麼URL不會改變,你已經將另一個視圖(page_index)的內容返回到當前視圖(add_page),這對我來說似乎是一個不好的模式。另外,我建議使用Django內置的[消息框架](https://docs.djangoproject.com/en/1)來代替滾動您自己的基於會話的消息傳遞解決方案。3/ref/contrib/messages /) – Anentropic

0

redirect具有重定向到一個實際的URL(這是一個HTTP重定向,而不僅僅是一個Python調用)。

即使您已將其設置爲默認情況下,視圖函數以error_message作爲kwarg被調用,但您的url conf中沒有'error_message'段。

由於這是您的索引頁面,您可能不希望將額外的路徑段添加到網址中,因此可能會使用GET變量來破解它。例如

def page_index(request): 
    if 'error_message' in request.GET: 
     print request.GET['error_message'] 

from django.core.urlresolvers import reverse 

def add_page(request): 
    return redirect('%s?error_message=test' % reverse('page_index')) 

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 

更新:

想到這裏,我走回家,雖然你的問題是關於重定向和kwargs等,可以說這裏是更好的選擇是使用Django的messages framework離開error_message完全你的看法kwargs中,GET變量等

from django.contrib import messages 

def add_page(request): 
    messages.add_message(request, messages.ERROR, 'test') 
    return redirect('page_index') 

這也避免了人們能夠用他們自己編寫的錯誤消息來製作網站,這可能會帶來安全風險。

2

你既可以爲每個錯誤消息的命名URL模式,並通過它在ARGS字典,像這樣:

url(r'^$', 'page_index', {'error_message': 'test'}, name='test_page_index'), 

,或者如果你願意把錯誤信息在實際的URL你可以選擇這樣的:

url(r'(?P"<"error_message">"\w+)/^$', 'page_index', name='page_index'), 

(請刪除「」圍繞「<」和「>」,不得不把他們在方括號或他們將被排除在外的形式回答,我想一切看起來像一個html標籤被過濾掉)

,並在視圖:

return redirect(reverse('page_index', args=['test']))