mco
mco

Reputation: 422

django redirect() with parameters

There have been several similar questions asked already but I couldn't find answer to my problem after spending loong hours.

In the code below when I redirect to "anotherView" from "myView" with parameter "username", it works fine as expected. But I need to include "range" parameter in this redirect too as this "range" is required for the template used after redirection. Whenever I try to do, I get several errors like:

-- "Don't mix *args and **kwargs in call to reverse()"

Is there a way to manage this the way I want?

   def myView(request):
      if request.user.is_authenticated():
        if request.method == 'POST':
                #my code comes here
                ....
                return redirect('anotherView', username=request.user.username, {"range": range(int(layout))})



   def anotherView(request,username):
      if request.user.is_authenticated():
        #my code comes here
          ....
          return redirect(something)

Upvotes: 9

Views: 37736

Answers (5)

Goran
Goran

Reputation: 6824

This is an old question but there is a small django_url_params module for this use case now.

Upvotes: 0

Storn White
Storn White

Reputation: 65

Rather than redirecting to the destination url, simply call the destination view function directly:

def myView(request):
    if request.user.is_authenticated():
        if request.method == 'POST':
            #my code comes here
            ....
            return anotherView(request, username, range)



def anotherView(request,username,range):
    if request.user.is_authenticated():
        #my code comes here
        ....
        return HttpResponse(something)

Upvotes: 2

Chris Pratt
Chris Pratt

Reputation: 239200

redirect is merely a wrapper around HttpResponseRedirect that automatically calls reverse for you to create the URL to redirect to. As a result, the parameters you pass to it, aren't arbitrary, they must be same you would pass to reverse and, specifically, only those required to create the URL.

Many people seem to have troubles understanding that data can't just be arbitrarily passed to a view. HTTP is a stateless protocol: each request exists on it's own, as if user had never been to any other page of the site. The concept of a session was created to provide a sense of "state" to a cohesive unit such as a site. With sessions, data is stored in some form of persistent storage and a "key" to look up that data is given to the client (typically the user's browser). On the next page load, the client sends the key back to the server, and the server uses it to look up the data to give the appearance of state.

As a result, if you need data from one view available in another, you need to add it to the session, do your redirect, and look up the data in the session from the next view.

Upvotes: 25

miki725
miki725

Reputation: 27861

Redirect takes the name of the view to redirect to, and any attributes to be passed to the other view. In your case anotherView only has two parameters - request and username however in the redirect you are passing more info to it.

You can try something like:

def anotherView(request, username, *args, **kwargs):
    ...

That will allow you to pass more attributes to it.

Edit

How about this in the original view:

kwargs = {"range": range(int(layout))}
return redirect('anotherView', username=request.user.username, **kwargs)

Upvotes: 1

Tom
Tom

Reputation: 22831

What are you trying to pass the "range" variable to? anotherView? There's no parameter to accept it. I think you may be looking for the reverse() function, but it's hard to tell.

Upvotes: 0

Related Questions