Django - passing a variable from a view into a url tag in template
Question: First of all, I apologize for the noobish question. I'm very new to Django and
I'm sure I'm missing something obvious. I have read many other posts here and
have not been able to find whatever obvious thing I am doing wrong. Thanks so
much for any help, I am on a deadline.

I am using Django 1.6 with Python 2.7. I have one app called dbquery that uses
a form to take data from the user and query a REST service. I am then trying
to display the results on a results page. Obviously there is more to add, this
is just a very simple start.

The problem is that I can't seem to get the autoincremented id field from my
search view into the url tag in the template properly. If I put the number 1
in like this `{% url 'dbquery:results' search_id=1 %}`, the page loads and
works well, but I can't seem to get the variable name right, and the django
documentation isn't helping- maybe this is obvious to most people. I get a
reverse error because the variable ends up always being empty, so it can't
match the results regex in my urls.py. I tested my code for adding an object
in the command line shell and it seems to work. Is there a problem with my
return render() statement in my view?

urls.py

    
    
    from django.conf.urls import patterns, url
    from dbquery import views
    
    urlpatterns = patterns('',
    
        # ex: /search/
        url(r'^$', views.search, name='search'),
    
        # ex: /search/29/results/ --shows response from the search
        url(r'^(?P<search_id>\d+)/results/', views.results, name ='results'),
    )
    

models.py

    
    
    from django.db import models
    from django import forms
    from django.forms import ModelForm
    import datetime
    
    # response data from queries for miRNA accession numbers or gene ids
    class TarBase(models.Model):
        #--------------miRNA response data----------
        miRNA_name = models.CharField('miRNA Accession number', max_length=100)
        species = models.CharField(max_length=100, null=True, blank=True)
        ver_method = models.CharField('verification method', max_length=100, null=True, blank=True)
        reg_type = models.CharField('regulation type', max_length=100, null=True, blank=True)
        val_type = models.CharField('validation type', max_length=100, null=True, blank=True)
        source = models.CharField(max_length=100, null=True, blank=True)
        pub_year = models.DateTimeField('publication year', null=True, blank=True)
        predict_score = models.DecimalField('prediction score', max_digits=3, decimal_places=1, null=True, blank=True)
        #gene name  
        gene_target = models.CharField('gene target name',max_length=100, null=True, blank=True)
        #ENSEMBL id
        gene_id = models.CharField('gene id', max_length=100, null=True, blank=True)
        citation = models.CharField(max_length=500, null=True, blank=True)
    
        def __unicode__(self):  
            return unicode(str(self.id) + ": " + self.miRNA_name) or 'no objects found!'
    

views.py

    
    
    from django.shortcuts import render, get_object_or_404
    from django.http import HttpResponse, Http404, HttpResponseRedirect
    from django.core.urlresolvers import reverse
    from dbquery.models import TarBase, SearchMainForm
    from tarbase_request import TarBaseRequest
    
    #main user /search/ form view
    def search(request):
        if request.method == 'POST': #the form has been submitted
            form = SearchMainForm(request.POST) #bound form
            if form.is_valid(): #validations have passed
                miRNA = form.cleaned_data['miRNA_name']
    
                u = TarBase.objects.create(miRNA_name=miRNA)
    
                #REST query will go here.
    
                #commit to database
                u.save()
    
                return render(request,'dbquery/results.html', {'id':u.id})
    
        else: #create an unbound instance of the form
            form = SearchMainForm(initial={'miRNA_name':'hsa-let-7a-5p'})
        #render the form according to the template, context = form
        return render(request, 'dbquery/search.html', {'form':form})
    
    
    #display results page: /search/<search_id>/results/ from requested search
    def results(request, search_id):
        query = get_object_or_404(TarBase, pk=search_id)
        return render(request, 'dbquery/results.html', {'query':query} )
    

templates: search.html

    
    
    <html>
    <head><h1>Enter a TarBase Accession Number</h1>
    </head>
    <body>
    <!--form action specifies the next page to load-->
    <form action="{% url 'dbquery:results' search_id=1 %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Search" />
    </form>
    
    </body>
    

results.html

    
    
    <html>
    <head><h1>Here are your results</h1>
    </head>
    <body>
    {{query}}
    
    </body
    


Answer: The search results aren't created and don't have an ID until after you submit
your form. The usual way to do this would be to have your form use its own URL
as the action, then have the view redirect to the results view after
successfully saving:

    
    
    from django.shortcuts import redirect
    
    def search(request):
        if request.method == 'POST': #the form has been submitted
            form = SearchMainForm(request.POST) #bound form
            if form.is_valid(): #validations have passed
                miRNA = form.cleaned_data['miRNA_name']
                u = TarBase.objects.create(miRNA_name=miRNA)
                #REST query will go here.
    
                #commit to database
                u.save()
    
                return redirect('results', search_id=u.id)
    
        else: #create an unbound instance of the form
            form = SearchMainForm(initial={'miRNA_name':'hsa-let-7a-5p'})
        #render the form according to the template, context = form
        return render(request, 'dbquery/search.html', {'form':form})
    

Then in your template:

    
    
    <form action="" method="post">
    

That causes your form to submit its data to the `search` view for validation.
If the form is valid, the view saves the results, then redirects to the
appropriate results page based on the ID as determined after saving.

