19

我试图让我的表单提交到一个路由,该路由将验证数据然后重定向回原始路由。

例如:

  • 用户加载页面 website.com/post
  • 表单将数据发布到 website.com/post-save
  • 用户被重定向回 website.com/post

Pyramid 给我带来了一些麻烦。

这是我精简的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)

这是我一直在玩的代码。它不仅不起作用,而且感觉很乱,很乱。当然有一种更简单的方法可以在 Pyramid 中“重定向 post-post”?

4

6 回答 6

27

您的问题很容易解决,方法是简单地发布到显示表单的相同 URL,并在 POST 成功时将用户重定向到页面之外。这样,在表单成功提交之前,您不会更改 URL。

如果您只是想 POST 到不同的 URL,那么您需要使用会话保存数据,因为您显然是在处理请求之间的表单数据。

通常,如果您希望能够处理表单中的错误,您将使用会话和闪存消息。为此,您只需在基本模板中添加一个显示 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()和循环浏览您选择的模板中的 Flash 消息request.session.pop_flash()

route_url如果您想标记主页视图以检查会话数据,还支持在生成的 url 上更改查询字符串。

您显然可以将查询字符串中的所有内容都传递回主页,但这是一个相当大的安全漏洞,会话可以帮助防范。

于 2011-04-12T20:19:27.717 回答
8

Pyramid 文档有一个特别重要的部分,其中包含以下示例:

from pyramid.httpexceptions import HTTPFound

def myview(request):
    return HTTPFound(location='http://example.com')
于 2011-04-10T06:24:01.390 回答
1

我这样做是这样的:

from pyramid.httpexceptions import HTTPCreated

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

这会发送 HTTP Created 代码,201

于 2011-04-15T11:39:05.127 回答
1

Pyramid 文档中有关于Redirect的内容,您可以在下面的链接中查看更多信息:

金字塔文档

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

编辑: 实际上你可以在客户端使用 Javascript 做到这一点,首先你应该向客户端发送特定的响应(要么闪烁一些数据或返回 Response 对象):

window.location = '{{ request.route_path("route_name") }}';
于 2016-12-02T21:10:23.533 回答
0

一种干净的方法是使用金字塔为不同的请求类型提供的“重载”,例如,您可以这样装饰您的方法:

@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 方法时处理另一种方法。同名,但有两种实现方式

于 2012-04-09T13:46:22.650 回答
0

假设您的主页是金字塔网络应用程序的默认视图,您可以执行以下操作:

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 视图是如何“添加”到您的配置器中的。如果您的主页实际上位于 /few/levels/deep/homepage ,则重定向可能如下所示:

        return HTTPFound(location=request.application_url + '/few/levels/deep/homepage')
于 2011-04-12T14:20:15.843 回答