【问题标题】:Django - passing a variable from a view into a url tag in templateDjango - 将变量从视图传递到模板中的 url 标签
【发布时间】:2015-02-02 17:24:36
【问题描述】:

首先,我为这个愚蠢的问题道歉。我对 Django 很陌生,我确信我遗漏了一些明显的东西。我在这里阅读了许多其他帖子,但无法找到我做错的任何明显的事情。非常感谢您的帮助,我的最后期限了。

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

问题是我似乎无法将搜索视图中的自动递增 id 字段正确地放入模板中的 url 标记中。如果我像这样{% url 'dbquery:results' search_id=1 %} 将数字 1 放入,页面加载并运行良好,但我似乎无法正确获取变量名,并且 django 文档没有帮助 - 也许这对大多数人来说是显而易见的。我收到一个反向错误,因为变量最终总是为空,因此它与我的 urls.py 中的结果正则表达式不匹配。我测试了在命令行 shell 中添加对象的代码,它似乎可以工作。在我看来,我的 return 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} )

模板: 搜索.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>

结果.html

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

</body

【问题讨论】:

  • 搜索ID是如何计算的?在我看来,这有点像本末倒置——在渲染 search.html 模板时,你真的知道搜索 ID 吗?
  • 在视图中创建了对象u,通过u.id可以访问到id(自增)。我已经用一个例子对其进行了测试。这能回答你的问题吗?
  • OK - 你的观点与通常的做法有些不同。我将在答案中展示标准方法。

标签: django django-templates


【解决方案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 重定向到相应的结果页面。

【讨论】:

  • 彼得,非常感谢。我不知道为什么这个概念对我来说如此棘手。我会支持你,但我还没有声望。当我回到我的常规机器上并最终确定答案时,我会对此进行测试。
  • 如果这对您有用,如果您愿意,可以接受此处描述的答案:meta.stackexchange.com/questions/5234/… 这不需要任何最低声誉。
  • 谢谢,看来我已经能够接受答案了,只是还没有投票。不过链接很好。
  • 我支持 Peter,因为无论如何他的解决方案都比我的更干净!
【解决方案2】:

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

这将允许您将您的 URL 指定为 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} )

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

【讨论】:

  • 第一个想法似乎是明智的建议,但我希望能够让页面 /search/1/ 例如显示搜索的详细信息,以便用户可以返回到它。像这样创建干净的 url 不是 Django 的原则之一吗?澄清一下,在第二部分中,您是说对我的 search.html 模板进行这些更改?对不起,如果这是一个愚蠢的问题,我只是在很短的时间内吸收了这么多信息。
  • 是的,在第二部分中,它指的是如何修改 HTML 模板中的内容。没错,我在这里解释的内容不如 /search/1 之类的内容干净,但它仍然允许用户返回它。也就是说,上面彼得的解决方案比我这里的解决方案要干净得多。
  • 我很欣赏替代视图和其他选项,因为我仍在学习中。
猜你喜欢
  • 2021-02-15
  • 2015-05-23
  • 2011-03-04
  • 1970-01-01
  • 2019-07-31
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多