【问题标题】:Passing raw SQL to Django template将原始 SQL 传递给 Django 模板
【发布时间】:2012-05-02 12:33:19
【问题描述】:

我需要显示大量不想分页的数据,因为我使用的是 jQuery 表格排序器,并且在视图中使用 Person.objects.all() 对数据库来说非常昂贵。加载时间太长,所以我试图在我的视图中执行原始 SQL。

我尝试使用 Django 的通用视图,但它们和 objects.all() 方法一样慢。

这是我的模型。本质上,我想显示所有人,同时计算他们出现了多少次,比如var1var2

class Person(models.Model):
    name = models.CharField(max_length=64, blank=True, null=True)
    last_name = models.CharField(max_length=64,)
    slug = models.SlugField()

class Object(models.Model):
    title = models.ForeignKey(Title)
    number = models.CharField(max_length=20)
    var1 = models.ManyToManyField(Person, related_name="var1_apps", blank=True, null=True)
    var2 = models.ManyToManyField(Person, related_name="var2_apps", blank=True, null=True)
    var3 = models.ManyToManyField(Person, related_name="var3_apps", blank=True, null=True)
    # ...   
    slug = models.SlugField()

from django.db import connection
    def test (request):
        cursor = connection.cursor()
        cursor.execute('SELECT * FROM objects_person')
        persons = cursor.fetchall() # fetchall() may not be the right call here?
        return render_to_response('test.html', {'persons':persons}, context_instance=RequestContext(request))

模板:

           <table class="table tablesorter">
               <thead>
                   <tr>
                   <th>Name</th>
                   <th>Var1</th>
                   <th>Var2</th>
                   <th>Var3</th>
                   </tr>
               </thead>
               <tbody>
                       {% for person in persons %}
                   <tr>
                       <td><a href="{{ person.get_absolute_url }}">{{  person.last_name }}{% if person.name %}, {{ person.name }}{% endif %}</a></td>
                       <td>{{ person.var1_apps.count }}</td>
                       <td>{{ person.var2_apps.count }}</td>
                       <td>{{ person.var3_apps.count }}</td>
                   </tr>
               {% endfor %}
               </tbody>
           </table>

它的作用是迭代空行,但如果我只调用{{ creator }},它将显示整个 SQL 表——这是我不想要的。我的查询一定有问题,因此感谢您的帮助。

【问题讨论】:

  • 这听起来令人惊讶,但.all() 完全转换为SELECT * FROM ...(在您的情况下)。所以我不明白你在做什么,你目前没有优化。

标签: django django-templates django-views


【解决方案1】:

问题不在于Person.objects.all()。当您遍历该查询集时,您正在对查询集中的 每个 项执行三个查询以计算计数。

答案是annotate 您的查询集,其中包含每个字段的计数。

# in the view
persons = Person.objects.annotate(num_var1_apps=Count('var1_apps'),
                                  num_var2_apps=Count('var2_apps'),
                                  num_var3_apps=Count('var3_apps'),
                                  )

# in the template
{% for person in persons %}
               <tr>
                   <td><a href="{{ person.get_absolute_url }}">{{  person.last_name }}{% if person.name %}, {{ person.name }}{% endif %}</a></td>
                   <td>{{ person.num_var1_apps }}</td>
                   <td>{{ person.num_var2_apps }}</td>
                   <td>{{ person.num_var3_apps }}</td>
               </tr>
{% end for %}

【讨论】:

  • 哦,快多了。不过,它现在显示的数字异常高,所以我不确定这是怎么回事。
  • 哦,必须将distinct=True 添加到Count (但添加后似乎明显变慢了?)。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-04-03
  • 2012-03-02
  • 2020-01-21
  • 2016-11-17
  • 2010-12-26
  • 2011-11-20
  • 2012-09-27
  • 1970-01-01
相关资源
最近更新 更多