Reputation: 898
There's lots of documentation about Django and the reverse()
method. I can't seem to locate my exact problem. Suppose I have two urlconfs like this:
url(r'ParentLists/$', main_page, name = "main_page"),
url(r'ParentLists/(?P<grade_level>.+)/$', foo, name = "foo")
and the two corresponding views like this:
def main_page(request):
if request.method == 'POST':
grade_level = request.POST['grade_picked']
return HttpResponseRedirect(reverse('foo', args = (grade_level,)))
else:
return render(request, 'index.html', context = {'grade_list' : grade_list})
def foo(request, grade_level):
grade_level = request.POST['grade_picked']
parent_list = # get stuff from database
emails = # get stuff from database
return render(request, 'list.html', context = {'grade_list' : grade_list, 'parent_list' : parent_list})
Here, list.html
just extends my base template index.html
, which contains a drop down box with grade levels. When the user goes to /ParentLists, the main_page
view renders index.html with the drop down box as it should.
When the user picks a grade level from the drop down box (say 5th Grade), the template does a form submit, and main_page
once again executes - but this time the POST branch runs and the HttpResponseRedirect
takes the user to /ParentLists/05. This simply results in an HTML table pertaining to grade 5 being displayed below the drop down box.
The problem is, when the user now selects say 10th Grade, the table updates to show the grade 10 content, but the URL displayed is still /ParentLists/05. I want it to be /ParentLists/10.
Clearly, after the first selection, the main_page
view never executes again. Only foo
does...and so the HttpResponseRedirect
never gets called. How should I reorganize this to get what I'm looking for? Thanks in advance!
Upvotes: 1
Views: 70
Reputation: 47374
As you correctly mentioned you will never redirect to foo() from foo().
So the simple way to fix this is just add similar code as in main_page() view:
def foo(request, grade_level):
if request.method == 'POST':
grade_level = request.POST['grade_picked']
return HttpResponseRedirect(reverse('foo', args = (grade_level,)))
else:
parent_list = # get stuff from database
emails = # get stuff from database
return render(request, 'list.html', context = {'grade_list' : grade_list, 'parent_list' : parent_list})
Please note that I remove grade_level = request.POST['grade_picked']
because as Nagkumar Arkalgud correctly said it is excessively.
Also instead of combination of HttpResponseRedirect
and reverse
you can use shortcut redirect
which probably little easy to code:
from django.shortcuts redirect
...
return redirect('foo', grade_level=grade_level)
Upvotes: 2
Reputation: 327
I would suggest you to use kwargs instead of args. The right way to use the view is:
your_url = reverse("<view_name>", kwargs={"<key>": "<value>"})
Ex:
return HttpResponseRedirect(reverse('foo', kwargs={"grade_level": grade_level}))
Also, you are sending "grade_level" to your view foo using the URL and not a POST value. I would remove the line:
grade_level = request.POST['grade_picked']
as you will override the grade_level sent to the method from the url.
Upvotes: 0