How i can match on the ?next=/nextpage/ value when i decorate a view in django with @login_required?
It’s not working on the “standard way” (in url.py via regular expression matching)!
Why it is not working on the standard way?
in urls.py:
(r'^login/$', 'foo.nb.views.signup'),
#(r'^login/?next=(?P<next>\S{1,250})$', 'foo.nb.views.signup'),
in views.py:
@login_required
def userpage(request):
return HttpResponse('logged in -> ON USERPAGE')
again views.py:
#def signup(request, next=""): # the login
def signup(request): # the login
""" Logs a user in """
if request.method=="POST" and request.POST['username'] and request.POST['password']:
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
#return redirect(next) # to sucess page
return redirect(request.GET['next']) # to sucess page
else:
pass
# Return to disabled account error message
else:
# return invalid login error message
pass
return render_to_response('NBlogin.html')
when i visit views.userpage i will be redirected to my login page as expectet, and the url have the next field passed like /login/?next=/oldpage/, when i login with a correct user i receive an error message which told me that no next variable is passed (user, password is set) as get neither as post, (but the login works fine, as expected)
edit: Django 1.2: login issue (GET parameter: next) have the same topic, but i dont see a solution…
edit2: after changing to request.GET[‘next’] the error message says:
Key 'next' not found in <QueryDict: {}>
edit3:
I had to change the view like so:
def signup(request): # the login
""" Logs a user in """
if request.method=="GET":
try:
next = request.GET['next']
except:
return render_to_response('NBlogin.html')
return render_to_response('NBlogin.html',{'next' : next})
if request.method=="POST" and request.POST['username'] and request.POST['password']:
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect(request.POST['next']) # to sucess page
else:
pass
# Return to disabled account error message
else:
# return invalid login error message
pass
return render_to_response('NBlogin.html')
and i had to add a hidden field in my template, thats it!:
<form action="/login/" method="post">
<p>Username:<input type="text" name="username"></p>
<p>Password:<input type="password" name="password">
<input type="hidden" name="next" value="{{next}}">
<input type="submit" value="login"></p>
</form>
Django only matches paths based on the path of the URL, not the querystring.
This means that anything after ‘?’ in your request from the server is not considered when deciding which view to serve up. Instead, that part of the string is turned into a dictionary like object.
so if you request:
Django will use
/login/to find the view, and will populaterequest.GETwith data{'next':'nextpage'}. Tell us what you’re actually trying to do and I’ll try to find a more Django-esque way for your to accomplish it.Edit after additional information supplied:
The querystring
?next=/nextpage/is probably not being sent when you submit the form with the POST method. Submitting the form will POST data to the URL specified in the form’s action attribute.