web-dev-qa-db-ja.com

PyramidでPOSTの後にリダイレクトするにはどうすればよいですか?

データを検証してから元のルートにリダイレクトするルートにフォームを送信させようとしています。

例えば:

  • ユーザーがページwebsite.com/postをロードします
  • フォームはデータをwebsite.com/post-saveにPOSTします
  • ユーザーは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で「After-POSTをリダイレクトする」より簡単な方法はありますか?

19
dave

問題は、フォームが表示されているのと同じURLにPOSTし、POSTが成功したときに、ユーザーをページからリダイレクトするだけです。そうすることで、フォームが正常に送信された場合、URLは変更されません。

POSTを別のURLに移動したいだけの場合は、明らかにリクエスト間でフォームデータを処理しているため、セッションを使用してデータを保存する必要があります。

通常、フォームのエラーを処理できるようにする場合は、セッションとフラッシュメッセージを使用します。これを行うには、ベーステンプレートにフラッシュメッセージを表示する場所を追加し、pyramid_beakerなどを使用してセッションサポートを設定するだけです。

ホームページが「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,
    }
_

フォームの検証に失敗した場合、最初にフォームをレンダリングしたのと同じコードを使用し、成功した場合にのみリダイレクトすることに注意してください。この形式では、送信で使用された値とデフォルト値をフォームに入力することもできます。

request.session.peek_flash()およびrequest.session.pop_flash()を使用して、選択したテンプレートのフラッシュメッセージをループできます。

_route_url_は、セッションデータを確認するためにホームページビューにフラグを立てる場合に、生成されたURLのクエリ文字列の変更もサポートします。

明らかに、クエリ文字列のすべてをホームページに戻すことができますが、これはセッションが保護するのに役立つ非常に大きなセキュリティの脆弱性です。

27

Pyramidのドキュメントには、特にオンポイントがあります section 次の例を使用します。

from pyramid.httpexceptions import HTTPFound

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

Pyramidのドキュメントには、Redirectに関するコンテンツがあります。詳細については、以下のリンクを参照してください。

ピラミッドドキュメント

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

編集済み:実際には、Javascriptを使用してクライアント側でそれを行うことができます。まず、特定の応答をクライアント側に送信する必要があります(データをフラッシュするか、応答オブジェクトを返します) )::

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

クリーンな方法は、さまざまなリクエストタイプに対してピラミッドによって提供される「オーバーロード」を使用することです。たとえば、次のようにメソッドを装飾できます。

_@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が使用されるときに処理されます。同じnameですが、2つの実装があります。

0
Antonio Beamud

私はそうするようにこれをします:

from pyramid.httpexceptions import HTTPCreated

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

これにより、HTTPで作成されたコード201が送信されます

ホームページがピラミッド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ビューがどのようにConfiguratorに「追加」されたかを知る必要があります。ホームページが実際に/ few/levels/deep/homepageにある場合、リダイレクトは次のようになります。

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