【问题标题】:How to redirect to previous page in Django after POST requestPOST请求后如何重定向到Django中的上一页
【发布时间】:2016-06-18 04:43:22
【问题描述】:

我遇到了一个我找不到解决方案的问题。我在导航栏中有一个按钮,它在所有页面上都可用,它是一个负责创建一些内容的按钮。

查看带有按钮的链接:

def createadv(request):
    uw = getuw(request.user.username)
    if request.method =='POST':
    form = AdverForm(request.POST, request.FILES)
    if form.is_valid():
        form.instance.user = request.user
        form.save()
        return HttpResponseRedirect('/', {'username': request.user.username, 'uw': uw})
    args = {}
    args.update(csrf(request))
    args['username'] = request.user.username
    args['form'] = AdverForm()
    args['uw'] = uw
    return  render_to_response('createadv.html', args)

如果您现在可以看到,我总是在创建内容后重定向到主页“/”,但我想回到我启动内容创建的页面。

【问题讨论】:

    标签: django redirect


    【解决方案1】:

    您可以在表单中添加next 字段,并将其设置为request.path。处理完表单后,您可以重定向到此路径的值。

    模板.html

    <form method="POST">
        {% csrf_token %}
        {{ form }}
        <input type="hidden" name="next" value="{{ request.path }}">
        <button type="submit">Let's Go</button>
    </form>
    

    views.py

    next = request.POST.get('next', '/')
    return HttpResponseRedirect(next)
    

    如果我没记错的话,这大致就是django.contrib.auth 为登录表单所做的。

    如果你通过一个中间页面,你可以通过查询字符串传递'next'值:

    some_page.html

    <a href="{% url 'your_form_view' %}?next={{ request.path|urlencode }}">Go to my form!</a>
    

    模板.html

    <form method="POST">
        {% csrf_token %}
        {{ form }}
        <input type="hidden" name="next" value="{{ request.GET.next }}">
        <button type="submit">Let's Go</button>
    </form>
    

    【讨论】:

    • 我正在努力使用中间页面和 CBV 来实现这一点。您的代码完全有意义,但我不断收到TypeError: quote_from_bytes() expected bytes。代码是从您的答案中复制的,除了 CBV,我使用 def get_success_url(self):。服务器抛出[08/Dec/2020 05:54:16] "POST /l/product/add/?next=/l/&lt;myslughere&gt;/edit/ HTTP/1.1" 500 118604,但这条路径看起来就像我所期望的那样......
    • 你在get_success_url() 里放了什么?它应该返回 url (next),而不是响应 (HttpResponseRedirect(next))。
    • 谢谢,这正是我的问题(返回HttpResponseRedirect(next) 而不仅仅是next。昨晚这里已经很晚了......现在就像一个魅力!
    • 如果我不想发布表单,有没有办法实现它?我想在项目选择页面上实现它。当用户想要将产品添加到他的愿望清单时,我想要一个指向产品页面的链接和一个指向愿望清单页面的后退按钮(这是一种让用户选择项目的表单)。
    • @Shahriar.M 是的,当然,您只需将 next={{ request.path|urlencode }} 查询参数传递给您的产品页面的 URL。然后你用href="{{ request.GET.next }}"创建你的后退按钮。
    【解决方案2】:

    您可以使用HTTP_REFERER 值:

    return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
    

    请注意,如果客户端禁用发送推荐人信息(例如,使用私人/隐身浏览器窗口),这将不起作用。在这种情况下,它将重定向到/

    【讨论】:

    • 在使用 HTTP 安全 (HTTPS) 连接时是否可以使用?
    • @EbramShehata 是的,如果原始页面和重定向页面都在安全连接上提供,它将起作用。
    【解决方案3】:

    你可以用这个

    return redirect(request.META.get('HTTP_REFERER'))
    

    确保导入这个

    from django.shortcuts import redirect
    

    【讨论】:

      【解决方案4】:

      我最喜欢的方法是将 request.path 作为 GET 参数提供给表单。 发布时它将通过它,直到您重定向。 在基于类的视图(FormView、UpdateView、DeleteView 或 CreateView)中,您可以直接将其用作 success_url。 在某处我读到混合使用 GET 和 POST 是一种不好的做法,但这种做法的简单性使其成为我的一个例外。


      示例 urls.py:

      urlpatterns = [
          path('', HomeView.as_view(), name='home'),
          path('user/update/', UserUpdateView.as_view(), name='user_update'),
      ]
      

      链接到模板内的表单:

      <a href="{% url 'user_update' %}?next={{ request.path }}">Update User</a>
      

      基于类的视图:

      class UserUpdateView(UpdateView):
          ...
          def get_success_url(self):
              return self.request.GET.get('next', reverse('home'))
      

      在基于函数的视图中,您可以按如下方式使用它:

      def createadv(request):
          uw = getuw(request.user.username)
          if request.method =='POST':
              form = AdverForm(request.POST, request.FILES)
              if form.is_valid():
                  form.instance.user = request.user
                  form.save()
                  next = request.GET.get('next', reverse('home'))
                  return HttpResponseRedirect(next)
      
          args = {}
          args.update(csrf(request))
          args['username'] = request.user.username
          args['form'] = AdverForm()
          args['uw'] = uw
          return  render_to_response('createadv.html', args)
      

      【讨论】:

        【解决方案5】:

        如果这有助于我在基于类的 UpdateView 中工作的人

        模板

        <form class="form" method="POST">
            {% csrf_token %}
        
            <!-- hidden form field -->
            <input type="hidden" id="previous_page" name="previous_page" 
            value="/previous/page/url">
        
            <!-- any other form fields -->
            {{ form.name|as_crispy_field }}
            {{ form.address|as_crispy_field }}
        
            <!-- form submit button -->
            <button class="btn btn-primary" type="submit" id="submit">Submit</button>
        </form>
        
        
        <!-- JS to insert previous page url in hidden input field -->
        <script>
            prev = document.getElementById("previous_page");
            prev.value = document.referrer;
        </script>
        
        
        

        views.py

        class ArticleUpdateView(generic.UpdateView):
        
            model = Article
            form_class = ArticleForm
            template_name = 'repo/article_form.html'
        
            def form_valid(self, form):
                form.instance.author = self.request.user
                # if form is valid get url of previous page from hidden input field
                # and assign to success url
                self.success_url = self.request.POST.get('previous_page')
                return super().form_valid(form)
        

        该视图现在会将您重定向回您单击“更新/编辑”按钮的页面。还会保留所有 URL 查询参数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-02-07
          • 2017-12-27
          • 2019-01-19
          • 2019-05-26
          • 1970-01-01
          • 2021-01-06
          • 2017-10-02
          相关资源
          最近更新 更多