How to redirect to previous page in Django after POST request

前端 未结 4 1825
自闭症患者
自闭症患者 2020-12-07 19:03

I face a problem which I can\'t find a solution for. I have a button in navbar which is available on all pages and it is a button responsible for creating some content.

相关标签:
4条回答
  • 2020-12-07 19:17

    You can use the HTTP_REFERER value:

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

    Note that this will not work if the client disabled sending referrer information (for example, using a private/incognito browser Window). In such a case it will redirect to /.

    0 讨论(0)
  • 2020-12-07 19:23

    You can add a next field to your form, and set it to request.path. After you processed your form you can redirect to the value of this path.

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

    This is roughly what django.contrib.auth does for the login form if I remember well.

    If you pass through an intermediate page, you can pass the 'next' value via the querystring:

    some_page.html

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

    template.html

    <form method="POST">
        {% csrf_token %}
        {{ form }}
        <input type="hidden" name="next" value="{{ request.GET.next }}">
        <button type="submit">Let's Go</button>
    </form>
    
    0 讨论(0)
  • 2020-12-07 19:26

    My favorite way to do that is giving the request.path as GET parameter to the form. It will pass it when posting until you redirect. In Class-Based-Views (FormView, UpdateView, DeleteView or CreateView) you can directly use it as success_url. Somewhere i read that it's bad practise to mix GET and POST but the simplicity of this makes it to an exception for me.


    Example urls.py:

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

    Link to the form inside of the template:

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

    Class-Based-View:

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

    In your function based view you can use it as follows:

    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)
    
    0 讨论(0)
  • 2020-12-07 19:33

    In case this helps someone I got this to work in class based UpdateView

    template

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

    The view now redirects you back to the page where you had clicked the "Update/Edit" button. Any URL query parameters are also preserved.

    0 讨论(0)
提交回复
热议问题