Djangoはパラメータ付きのredirect()を返します


83

ビュー関数で、別のビューを呼び出してデータを渡したい:

return redirect('some-view-name', backend, form.cleaned_data)

、ここで、backendはregistration.backendsオブジェクトであり、form.cleaned_dataはフォームデータのdictです(ただし、発生を防ぐために、両方を* argsまたは** kwargsとして送信する必要があります Don't mix *args and **kwargs in call to reverse()!エラーが発生します)。私がドキュメントで見つけたものから:

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

'some-view-name'引数を指定する必要があるようですが、それは単にビュー関数の名前ですか、それともURLの名前ですか?だから私はそれをdjango-registrationで行われるのと同じようにしたいと思います、ここで:

to, args, kwargs = backend.post_registration_redirect(request, new_user)
return redirect(to, *args, **kwargs)

def post_registration_redirect(self, request, user):
    return ('registration_complete', (), {})

では、ビュー関数を直接呼び出すことはできますか、それともURLを指定する必要がありますか?そして、もっと重要なのは、私のfunciotn呼び出し(および必要に応じてURL)がどのように見えるべきかということです。バックエンドとcleaned_dataの両方が、後で使用するためにこのビューを通過するだけです。私はこれを試しましたが、それは不適切です:

url(r'^link/$', some-view-name)   
def some-view-name(request, *args):

これと同様に :

return redirect('some_url', backend=backend, dataform.cleaned_data) 
url(r'^link/$', some-view-name)    
def some-view-name(request, backend, data):

それでもNoReverseMatch。しかし、django-registrationでは、次のようなものを見てきました:

url(r'^register/$',register,{'backend': 'registration.backends.default.DefaultBackend'}, name='registration_register'),

def register(request, backend, success_url=None, form_class=None,
             disallowed_url='registration_disallowed',
             template_name='user/login_logout_register/registration_form.html',
             extra_context=None):

回答:


66

まず、URL定義はパラメータをまったく受け入れません。パラメータをURLからビューに渡す場合は、urlconfでパラメータを定義する必要があります。

第二に、cleaned_dataディクショナリに何が起こると予想しているかがまったく明確ではありません。POSTにリダイレクトできないことを忘れないでください-これはHTTPの制限であり、Djangoではありません-したがって、cleaned_dataはURLパラメーター(恐ろしい)であるか、少し良いことに、一連のGETパラメーターである必要があります-したがって、URL次の形式になります:

/link/mybackend/?field1=value1&field2=value2&field3=value3

等々。この場合、field1、field2、field3はURLconf定義に含まれていませんrequest.GET。これらは、を介してビューで使用できます。

したがって、urlconfは次のようになります。

url(r'^link/(?P<backend>\w+?)/$', my_function)

ビューは次のようになります。

def my_function(request, backend):
   data = request.GET

逆は(インポート後urllib):

return "%s?%s" % (redirect('my_function', args=(backend,)),
                  urllib.urlencode(form.cleaned_data))

コメント後に編集

これまで行ってきたように、リダイレクトとリバースを使用することの全体的なポイントは、URLに移動することです。これにより、ブラウザーが新しいURLにリダイレクトし、それを呼び出すHTTPコードが返されます。

コード内からビューを呼び出すだけの場合は、直接呼び出すだけです。reverseを使用する必要はまったくありません。

とはいえ、データを保存するだけの場合は、セッションに配置するだけです。

request.session['temp_data'] = form.cleaned_data

このビューでcleaned_dataを操作せず、後で使用するために渡すだけの場合はどうでしょうか。cleaned_data dictに多くのフィールドがあるので、get文字列として渡さないようにします:)
muntu 2010

このコメントがわかりません。必要に応じて質問を更新し、より詳細に説明してください。
ダニエルローズマン2010

この2番目のビューは、この送信されたデータのみを保存して、さらに使用できるようにします。しかし、URLを提供する必要がありますか?ドキュメントからは、ビューを直接呼び出しているように見えます。また、redirect()(django-registrationで行われるように)とURL(register関数のこのdictのように)でバックエンドとデータを含む辞書を送信することを望んでいましたが、私が見るところ、それは不可能ですか?
muntu 2010

はいはいはいそれだけです!! 私はセッションを完全に忘れてそれに多くの時間を無駄にしました:/くそー、ありがとう!!
muntu 2010

1
URLが必要ない場合は、関数を呼び出すだけの良い点です。
maxbellec 2015年

60

urls.py:

#...    
url(r'element/update/(?P<pk>\d+)/$', 'element.views.element_update', name='element_update'),

views.py:

from django.shortcuts import redirect
from .models import Element


def element_info(request):
    # ...
    element = Element.object.get(pk=1)
    return redirect('element_update', pk=element.id)

def element_update(request, pk)
    # ...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.