2011-04-10 95 views
18

我試圖讓我的表單提交到將驗證數據然後重定向回原始路由的路由。如何在金字塔POST後重定向?

例如:

  • 用戶負載website.com/post
  • 表單發佈的數據website.com/post-save
  • 用戶的頁面被重定向回website.com/post

金字塔給我一些麻煩做到這一點。

這裏是我的瘦身views.py

def _get_link_form(post_data): 
    """ Returns the initialised form object """ 

    return LinkForm(post_data) 

def home_page(request): 

    form = _get_link_form(request.POST) 
    return {'form' : form} 

def save_post(request): 
    """ form data is submitted here """" 

    form = _get_link_form(request.POST) 

    if not form.validate(): 
     return home_page(request, form) 

這是我一直在玩弄代碼。它不僅不起作用,而且感覺混亂並且被黑了。肯定有一種更簡單的方式來在金字塔中「重新定向後」?

回答

8

金字塔文檔有一個特別的點section用下面的例子:

from pyramid.httpexceptions import HTTPFound 

def myview(request): 
    return HTTPFound(location='http://example.com') 
+0

重定向很容易。問題是,我如何重定向到'home_page'併發送'save_post'中發現的表單錯誤? – dave 2011-04-10 06:43:17

+0

解決這個問題的一種方法是按照你現在做事情的方式進行逆轉:讓'home_page'也是表單提交的視圖,然後只有在提交成功時才做重定向。所以,如果你需要顯示錯誤,'home_page'已經有了它需要的表單對象。 – 2011-04-10 06:59:27

+0

我正在考慮,但我有兩個不同的視圖可調用,將呈現形式。我可以讓他們都提交到一個,主,視圖可調用(home_page,在這個例子中),但它會很好,如果每個視圖可調用提交後可以重定向回自己 - 如果這是有道理的... – dave 2011-04-10 07:14:15

0

假設您的主頁是你的金字塔的Web應用程序的默認視圖,你可以這樣做:

def _get_link_form(post_data): 
    """ Returns the initialised form object """ 

    return LinkForm(post_data) 

def home_page(request): 

    form = _get_link_form(request.POST) 
    return {'form' : form} 

def save_post(request): 
    form = _get_link_form(request.POST) 

    if not form.validate(): 
     from pyramid.httpexceptions import HTTPFound 
     return HTTPFound(location=request.application_url) 

基本上你需要知道如何將home_page視圖「添加」到配置器中。如果你的網頁實際上是住在/數/水平/深/主頁,然後重定向可能是這樣的:

 return HTTPFound(location=request.application_url + '/few/levels/deep/homepage') 
+0

嘿洛基,感謝jinja2補充。 – 2011-04-15 12:56:09

+0

使用'HTTPFound'產生HTTP響應代碼302,因此下一個請求將是GET,而不是原始的POST。因此,您不會在'home_page'視圖中獲取表單的數據,因爲您正在查看'request.POST'。 – 2016-02-16 21:12:00

26

您的問題是最容易被簡單地張貼到您的形式在顯示相同的URL解決了,只需在POST成功時將用戶從頁面重定向。以這種方式,直到表單成功提交您不會更改網址。

如果您只是想要POST到另一個URL,那麼您需要使用會話保存數據,因爲您顯然正在處理請求之間的表單數據。

通常,如果您希望能夠處理表單中的錯誤,您可以使用會話和Flash消息。要做到這一點,只需添加一個Flash消息的位置,使其顯示在您的基本模板中,並使用類似pyramid_beaker的設置支持安裝會話。

假設你的主頁是在「家」命名的路線設置:

from pyramid.httpexceptions import HTTPFound 

def myview(request): 
    user = '<default user field value>' 
    if 'submit' in request.POST: 
     user = request.POST.get('user') 
     # validate your form data 
     if <form validates successfully>: 
      request.session.flash('Form was submitted successfully.') 

      url = request.route_url('home') 
      return HTTPFound(location=url) 
    return { 
     # globals for rendering your form 
     'user': user, 
    } 

注意一下,如果表單無法驗證你用你對原本呈現形式相同的代碼,且僅當你是否成功重定向。這種格式也可以處理使用提交中使用的值填充表單和默認值。

您可以使用request.session.peek_flash()request.session.pop_flash()循環選擇模板中的Flash消息。

route_url如果您想標記主頁視圖以檢查會話數據,也支持在生成的url上更改查詢字符串。

顯然,您只需將查詢字符串中的所有內容都傳回主頁,但這是一個相當大的安全漏洞,會話可以幫助防範。

0

我這樣做像這樣:

from pyramid.httpexceptions import HTTPCreated 

response = HTTPCreated() 
response.location = self.request.resource_url(newResource) 
return response 

此發送HTTP創建的代碼,201

0

清潔的方法是使用由金字塔不同的請求類型,POR實施例提供的「過載」,則可以裝飾你的方法是這樣的:

@action(request_method='GET', 
     renderer='mypackage:/templates/save.mako', 
     name='save') 
def save(request): 
    ''' Fill the template with default values or leave it blank''' 
    return {} 


@action(request_method='POST', 
     renderer='mypackage:/templates/save.mako', 
     name='save') 
def save_post(request): 
    """ form data is submitted here """" 
    # process form 

在HTML,必須調用動作形式,像

<form method="POST" id="tform" action="${request.route_url('home', action='save')}">

這樣,一種方法在使用方法POST時處理,而另一種方法在使用GET時處理。同名名稱,但有兩個實現。

+0

當然,但在POST分支上,當驗證失敗時,通常應該這樣做,在GET中做什麼...... – pihentagy 2013-02-04 15:46:23

+0

金字塔中沒有'action'裝飾器。我猜你正在使用* pyramid_handlers *包中的['action'](http://pyramid-handlers.readthedocs.org/en/latest/api.html#pyramid_handlers.action)裝飾器。 – 2016-02-16 20:05:28

+0

我想你錯過了提交表單使用POST到**不同的網址,然後用於獲取表單的問題。兩個處理程序都使用相同的名稱('save')註冊,因此它們可以在相同的url下訪問。 – 2016-02-16 20:56:36

0

金字塔文檔具有內容有關重定向,你可以在下面的鏈接查看詳細信息:

Pyramid documentation

import pyramid.httpexceptions as exc 
raise exc.HTTPFound(request.route_url("section1")) # Redirect