在 Pyramid 中 POST 后如何重定向?

发布于 2024-10-31 09:57:32 字数 715 浏览 3 评论 0原文

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

例如:

  • 用户加载页面 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)

这是我一直在使用的代码。它不仅不起作用,而且还给人一种凌乱、被砍掉的感觉。当然有一种更简单的方法可以在 Pyramid 中“POST 后重定向”吗?

I'm trying to have my form submit to a route which will validate the data then redirect back to the original route.

For example:

  • User loads the page website.com/post
  • Form POSTs the data to website.com/post-save
  • User gets redirected back to website.com/post

Pyramid is giving me some troubles doing this.

Here's my slimmed down 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)

This is the code I've been playing around with. Not only does it not work, it also feels messy and hacked up. Surely there's a simpler way to 'redirect after-POST' in Pyramid?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏末的微笑 2024-11-07 09:57:32

您的问题最容易解决,只需 POST 到表单显示的同一 URL,并在 POST 成功时将用户重定向到页面之外。这样,在表单成功提交之前,您无需更改 URL。

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

通常,如果您希望能够处理表单中的错误,您将使用会话和闪现消息。为此,您只需添加一个位置,以便在基本模板中显示 Flash 消息,并使用诸如 Pyramid_beaker 之类的工具设置会话支持。

假设您的主页设置在“home”命名路由上:

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 上的查询字符串。

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

Your problem is most easily solved by simply POSTing to the same URL that your form is shown at, and simply redirecting the user away from the page when the POST is successful. That way until the form is successfully submitted you do not change URLs.

If you're just dying to POST to a different URL, then you need to save the data using sessions, since you're obviously handling the form data between requests.

Typically if you want to be able to handle errors in your forms you would use a session and flash messages. To do this you simply add a location for flash messages to appear in your base template and setup session support using something like pyramid_beaker.

Assuming your home page is setup at the 'home' named-route:

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,
    }

Notice how if the form fails to validate you use the same code you did to render the form originally, and only if it is successful do you redirect. This format can also handle populating the form with the values used in the submission, and default values.

You can loop through the flash messages in your template of choice using request.session.peek_flash() and request.session.pop_flash().

route_url supports mutating the query string on the generated url as well, if you want to flag your home page view to check the session data.

You can obviously just pass everything in the query string back to the home page, but that's a pretty big security vulnerability that sessions can help protect against.

眉黛浅 2024-11-07 09:57:32

金字塔文档有一个特别重要的部分,示例如下:

from pyramid.httpexceptions import HTTPFound

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

The Pyramid documentation has a particularly on-point section with the following example:

from pyramid.httpexceptions import HTTPFound

def myview(request):
    return HTTPFound(location='http://example.com')
魔法唧唧 2024-11-07 09:57:32

我这样做:

from pyramid.httpexceptions import HTTPCreated

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

这会发送 HTTP 创建的代码,201

I do this like so:

from pyramid.httpexceptions import HTTPCreated

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

This sends the HTTP Created code , 201

心舞飞扬 2024-11-07 09:57:32

Pyramid 文档包含有关重定向的内容,您可以在以下链接中查看更多信息:

金字塔文档

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

编辑:
实际上,您可以使用 Javascript 在客户端执行此操作,首先您应该向客户端发送特定响应(闪烁一些数据或返回 Response 对象):

window.location = '{{ request.route_path("route_name") }}';

The Pyramid documentation has content about Redirect, you can see more information in below link :

Pyramid documentation

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

Edited:
Actually you can do that on client side with Javascript, first you should send particular response to client side(either with flashes some data or return Response object):

window.location = '{{ request.route_path("route_name") }}';
铜锣湾横着走 2024-11-07 09:57:32

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

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')

Assuming your homepage is the default view of your pyramid web app, you can do:

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)

Basically you need to know how the home_page view was "added" to your Configurator. If your homepage actually lives at /few/levels/deep/homepage then a redirect might look like this:

        return HTTPFound(location=request.application_url + '/few/levels/deep/homepage')
羅雙樹 2024-11-07 09:57:32

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

@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 中,您必须调用操作表单,例如

这样在使用POST方法的时候处理一个方法,另一个当使用 GET 时。相同的名称,但有两种实现。

A clean way is using the "overload" provided by pyramid for different request types, por example, you can decorate your methods this way:

@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

In the HTML, you must call the action form, like

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

This way, one method is processed when the method POST is used, and the other when the GET is used. The same name, but two implementations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文