【问题标题】:Django return redirect() with parametersDjango 带参数返回 redirect()
【发布时间】:2011-03-13 16:48:48
【问题描述】:

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

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

,其中 backend 是 registration.backends 对象,而 form.cleaned_data 是表单数据的字典(但两者都必须作为 *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):

【问题讨论】:

    标签: python django redirect parameter-passing


    【解决方案1】:

    我喜欢在 django3 中这样做

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 这些技巧/方式/deep_knowledge_items 真的很有帮助。非常感谢。
      【解决方案3】:

      首先,您的 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
      

      【讨论】:

      • 如果我不会在此视图中对cleaned_data 进行操作,而只是将其传递以供以后使用?我在cleaned_data dict中有很多字段,所以我想避免将它们作为获取字符串传递:)
      • 我不明白这条评论。请更详细地解释,如有必要,请更新您的问题。
      • 第二个视图将仅存储此发送的数据以供进一步使用。但是你确定我需要提供它的网址吗?从文档看来我只是直接调用视图。我也希望只在 redirect() 中发送一个带有后端和数据的字典(就像在 django-registration 中所做的那样),然后在 url 中(就像 register 函数中的这个字典),但从我看来这是不可能的?
      • 是的,是的,就是这样!我已经浪费了这么多时间,完全忘记了会话:/该死的,谢谢!!
      • 如果不需要 URL,只需调用该函数即可。
      猜你喜欢
      • 1970-01-01
      • 2016-08-31
      • 2021-09-21
      • 2018-03-26
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      相关资源
      最近更新 更多