Reputation: 422
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
Reputation: 6824
This is an old question but there is a small django_url_params module for this use case now.
Upvotes: 0
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
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
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