Django - 将视图中的变量传递给模板中的url标记

时间:2014-12-04 17:51:45

标签: django django-templates

首先,我为这个noobish问题道歉。我对Django很新,而且我确定我错过了一些明显的东西。我在这里读过很多其他帖子,但却找不到我做错的任何明显的事情。非常感谢您的帮助,我正处于截止日期。

我正在使用Django 1.6和Python 2.7。我有一个名为dbquery的应用程序,它使用表单从用户获取数据并查询REST服务。然后我尝试在结果页面上显示结果。 显然还有更多补充,这只是一个非常简单的开始。

问题在于我似乎无法将搜索视图中自动增加的id字段正确地插入到模板中的url标记中。如果我像这样{% url 'dbquery:results' search_id=1 %}输入数字1,页面加载并运行良好,但我似乎无法正确获取变量名称,并且django文档没有帮助 - 也许这对大多数人来说很明显。我得到一个反向错误,因为变量最终总是为空,所以它不能匹配我的urls.py中的结果正则表达式。我测试了我的代码在命令行shell中添加一个对象,它似乎工作。在我的视图中返回render()语句是否有问题?

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

模板: 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

2 个答案:

答案 0 :(得分:1)

在您提交表单之前,搜索结果尚未创建且没有ID。通常的方法是让表单使用自己的URL作为操作,然后在成功保存后将视图重定向到结果视图:

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

然后在你的模板中:

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

这会导致您的表单将其数据提交到search视图以进行验证。如果表单有效,视图将保存结果,然后根据保存后确定的ID重定向到相应的结果页面。

答案 1 :(得分:0)

在这种情况下,您最好将搜索参数作为参数传递,例如http://host/results?search_id=<your search value>

这样您就可以将自己的网址指定为url(r'results/', views.results, name ='results'),并在模板中引用{% url dbquery:results %}

然后在您的视图中,您将其更改为:

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

或者,如果您希望查询实际显示在网址中,请将表单更改为method="get",将request.POST.get('search_id')更改为request.GET.get('search_id')