Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中对相关对象进行迭代:循环查询集或使用一行选择相关(或预取相关)_Python_Django_Orm - Fatal编程技术网

Python 在Django中对相关对象进行迭代:循环查询集或使用一行选择相关(或预取相关)

Python 在Django中对相关对象进行迭代:循环查询集或使用一行选择相关(或预取相关),python,django,orm,Python,Django,Orm,我有一个新闻稿应用程序,其中一份新闻稿在每期中有多篇文章。我想在线显示一个摘要页面,列出时事通讯的年份、卷和标签,然后在无序列表中显示该期的所有文章。我对Django很陌生,所以我正在努力确定最好的方法 我已定义模型(仅相关部分): Models.py: 班级时事通讯(models.Model): 音量=型号。外键(音量) 年份=型号。整型字段() 季节=型号.CharField(最大长度=6,选择数=数量/季节) label=models.CharField(最大长度=20) number=m

我有一个新闻稿应用程序,其中一份新闻稿在每期中有多篇文章。我想在线显示一个摘要页面,列出时事通讯的年份、卷和标签,然后在无序列表中显示该期的所有文章。我对Django很陌生,所以我正在努力确定最好的方法

我已定义模型(仅相关部分):

Models.py

班级时事通讯(models.Model):
音量=型号。外键(音量)
年份=型号。整型字段()
季节=型号.CharField(最大长度=6,选择数=数量/季节)
label=models.CharField(最大长度=20)
number=models.IntegerField()
类文章(models.Model):
时事通讯=型号。外键(时事通讯)
截面=模型。外键(截面)
title=models.CharField(最大长度=200)
我想在网上看到的是:

<h2>Spring 2012</h2>
<p>Volume 14, Number 1</p>
<ul>
    <li>Foo</li>
    <li>Bar</li>
    <li>Baz</li>
</ul>

<h2>Winter 2011</h2>
<p>Volume 13, Number 4</p>
<ul>
  <li>Boffo</li>
</ul>
然后使用以下模板进行渲染:

时事通讯\u list.html

{%block content%}
{新闻稿中的文章百分比,新闻稿列表中的文章百分比}
{{newsletter.label}
卷{{newsletter.Volume},编号{{newsletter.Number}

{{newsletter.article}

    {%对于文章中的%a}
  • {{a.title}}
  • {%endfor%}
{%endfor%} {%endblock%}
非常简单,但由于我对Django还很陌生,我想知道我所做的工作是否完全没有效率,因为它强大的ORM。如果有更快的方法,我希望不必在运行中列出一个列表,然后将这两个列表一起列出


TIA。

您现在所采用的方法将非常低效,因为它将导致1+N个查询。也就是说,1用于查询所有新闻稿,然后1用于每次评估这些
n.article\u set.all()
结果。因此,如果在第一个查询中有100个Newletter对象,那么将执行101个查询

这是使用
prefetch\u related
的绝佳理由。它只会导致2个查询。一个是获取时事通讯,一个是批量获取相关文章。尽管您仍然可以继续使用
zip
来组织它们,但它们已经被缓存了,因此您可以直接将查询传递到模板并循环查询

查看

newsletters = Newsletter.objects.prefetch_related('article_set').all()\
                    .order_by('-year', '-number')

return render_to_response('newsletter/newsletter_list.html',
                          {'newsletter_list': newsletters})
模板

{% block content %}
  {% for newsletter in newsletter_list %}
    <h2>{{ newsletter.label }}</h2>
    <p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
    <p>{{ newsletter.article }}</p>
    <ul>
    {% for a in newsletter.article_set.all %}
      <li>{{ a.title }}</li>
    {% endfor %}
    </ul>
  {% endfor %}
{% endblock %}
{%block content%}
{时事通讯中的时事通讯%u列表%}
{{newsletter.label}
卷{{newsletter.Volume},编号{{newsletter.Number}

{{newsletter.article}

    {newsletter.article_set.all%}
  • {{a.title}}
  • {%endfor%}
{%endfor%} {%endblock%}
太棒了!我以为我做这件事效率很低。我刚刚尝试了您的代码示例,不幸的是,newsletter.article\u set.all上的for循环没有返回任何内容?{%a在newsletter.articles\u set.all%}知道我做错了什么吗?谢谢你写了
articles\u set.all
当它应该是
article\u set.all
@tatlar时。有关更多信息,请参阅。道歉。非常感谢你们两位@jdi是否有类似的解决方案,如果我希望每个新闻稿都有最新的5篇文章?@Acute-使用模板标记{%作为新闻稿中的文章集。所有|切片:“5”%}将得到前五个结果。您需要确保已在视图中使用order_by对查询集进行了排序。