Django - passing a variable from a view into a url tag in template

依然范特西╮ 提交于 2019-12-08 09:29:10

问题


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

回答1:


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.




回答2:


In this case, you're likely better off passing your search parameter as a parameter, such as http://host/results?search_id=<your search value>.

This will allow you to specify your URL as url(r'results/', views.results, name ='results') and reference in your template as {% url dbquery:results %}.

Then in your view, you would change it to:

def results(request):
    search_id = request.POST.get('search_id')
    query = get_object_or_404(TarBase, pk=search_id)
    return render(request, 'dbquery/results.html', {'query':query} )

Or if you want the query to actually show in the URL, change the form to be method="get" and the request.POST.get('search_id') to request.GET.get('search_id')



来源:https://stackoverflow.com/questions/27300680/django-passing-a-variable-from-a-view-into-a-url-tag-in-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!