Django 返回带参数的重定向

119 投票
4 回答
263290 浏览
提问于 2025-04-16 01:01

在我的视图函数中,我想调用另一个视图,并把数据传递给它:

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

这里的backend是一个注册对象,form.cleaned_data是一个包含表单数据的字典(但这两个必须以*args或**kwargs的形式传递,以避免出现不要在调用reverse()时混合使用*args和**kwargs!的错误)。根据我在文档中找到的信息:

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

看起来我需要提供'some-view-name'这个参数,但这个参数是视图函数的名字,还是网址的名字呢?所以我想让它和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', (), {})

好吧,那么,我可以直接调用我的视图函数吗,还是需要提供一个网址?更重要的是,我的函数调用(如果需要的话,网址)应该是什么样子的?backend和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):

4 个回答

13

我在django3中很喜欢这样做

redirect_url = reverse('my_function', args=(backend,))
parameters = urlencode(form.cleaned_data)
return redirect(f'{redirect_url}?{parameters}')
100

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)
    # ...
84

首先,你的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——它会返回一个Http代码,导致浏览器重定向到新的URL,并调用它。

如果你只是想在代码中调用视图,那就直接调用,不需要使用反向。

话虽如此,如果你只想存储数据,那就把它放在会话中:

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

撰写回答