djangourlconf

Django not displaying correct URL after reverse


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!


Solution

  • 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)