wu peter
wu peter

Reputation: 97

Django programming - how to redirect to original url

I have a website www.example.com with many pages.

On each page I put one special unique button, which link to unique URL www.example.com/task1.

Once click this button, Django urls patten will pass it to dedicated function task1 for me.

My question is how to refresh original URL after completion of the task1, I find request.path only could transfer /task1. Any idea to get back the URL which the button allocated. Please refer to my task1 function.

def task1(request):
    '''
    do  task1  job
    '''
    return render(request, request.path)  
    # above return could not render the original URL which I clicked from.

Upvotes: 3

Views: 2730

Answers (1)

nimasmi
nimasmi

Reputation: 4138

In the link to your task1 function, include the current URL as a query string:

<a href="task1/?next={{ request.get_full_path }}">Task 1</a>

Then in the view:

from django.shortcuts import redirect

def task1(request):
    # Do task 1...
    next = request.GET.get('next')
    if next:
        return redirect(next)
    # some fallback here…

For completeness, and based on @Alasdair's comments, you can mimic what Django does to ensure that the redirect URL is safe:

from django.conf import settings
from django.shortcuts import redirect
from django.utils.http import url_has_allowed_host_and_scheme


def task1(request):
    # Do task 1...
    pass

    # Return the user-originating redirect URL if it's safe.
    redirect_to = request.GET.get("next")
    url_is_safe = url_has_allowed_host_and_scheme(
        url=redirect_to,
        allowed_hosts=settings.ALLOWED_HOSTS,
        require_https=request.is_secure(),
    )
    if url_is_safe and redirect_to:
        return redirect(redirect_to)
    return redirect("http://www.example.com")

For the original see https://github.com/django/django/blob/master/django/contrib/auth/views.py#L68, though that's a class-based view, rather than a function-based view as you have here.


In a bid to future-proof this answer for a while longer:

  1. Read the comments below; @mlissner is talking sense, for example, regarding the renaming of this in Django 3+,
  2. Know that there are security implications with acting on user input, even from a query string and GET request, and if you're not writing to the database.

Upvotes: 8

Related Questions