Django 返回带参数的重定向
在我的视图函数中,我想调用另一个视图,并把数据传递给它:
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 个回答
我在django3中很喜欢这样做
redirect_url = reverse('my_function', args=(backend,))
parameters = urlencode(form.cleaned_data)
return redirect(f'{redirect_url}?{parameters}')
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)
# ...
首先,你的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