django复杂查询集注释

django复杂查询集注释,django,django-queryset,Django,Django Queryset,我想在queryset中添加一些统计数据,这些数据是根据每个用户的页面请求计算出来的,并显示在一个大表中。annotate方法可能是最好的选择,但我一直坚持将创建的查询集合并到一个查询集,以便在模板中更容易操作。首选queryset类型对数据进行排序 以下是我的应用程序的极其简化的原理。模板和模型不能被触摸,因为这显然是我想要的结果。本例中未实现按列的数据排序 以下是模型: class Poll(models.Model): question = models.CharField(max

我想在queryset中添加一些统计数据,这些数据是根据每个用户的页面请求计算出来的,并显示在一个大表中。annotate方法可能是最好的选择,但我一直坚持将创建的查询集合并到一个查询集,以便在模板中更容易操作。首选queryset类型对数据进行排序

以下是我的应用程序的极其简化的原理。模板和模型不能被触摸,因为这显然是我想要的结果。本例中未实现按列的数据排序

以下是模型:

class Poll(models.Model):
    question = models.CharField(max_length=200, unique=True)

class Vote(models.Model):
    poll = models.ForeignKey(Poll)
    accept = models.BooleanField()
    comment = models.CharField(max_length=200, unique=True)
    censored = models.BooleanField()
以下是观点:

def summaryView(request):
    …
    contexte['poll_list'] = «insert code here»
    …
    return render_to_response('summary.html, contexte)
以下是模板:

<table>
  <thead>
    <tr>
      <th>
        Poll question
      </th>
      <th>
        Number of votes
      </th>
      <th>
        Number of uncensored "yes" votes
      </th>
      <th>
        Number of censored votes
      </th>
    </th>
  </thead>
  <tbody>
    {% for poll in poll_list %}
      <tr>
        <td>
          {{ poll.question }}
        </td>
        <td>
          {{ poll.numUncensoredYesVotes }}
        </td>
        <td>
          {{ poll.numCensoredVotes }}
        </td>
      </tr>
    {% endfor %}
  </tbody>
</table>

民意测验问题
票数
未经审查的“赞成”票数
经审查的票数
{poll_list%}中的轮询为%
{{poll.question}
{{poll.numUncensoredYesVotes}
{{poll.numcensoreddowers}
{%endfor%}

难点在于创建未经审查的“是”票数。Count()聚合函数不接受筛选器。

在python中,您始终可以通过3个查询(只需在python中手动加入查询集)来完成此操作,但以下是一个查询的实现方法: 如果需要注释的轮询查询集是由query1生成的,则可以使用一种解决方案

contexte['poll_list'] = Poll.objects.raw(
    ' select A.*, B.numcensoredvotes, C.numuncensoredyesvotes from 
    ( query1 ) A left join (query2) B on A.id = B.poll_id
    left join (query3) C on A.id = C.poll_id' )
其中query2和query3是聚合查询。 您可以通过以下方式访问查询集的查询:

poll_list = Poll.objects.filter(...)
poll_list.query.get_initial_alias()
(query1,q1param) = poll_list.query.sql_with_params()
您也可以对聚合查询(上面的query2和query3)执行此操作,也可以手工编写


另请参见执行非平凡queryset注释的相关场景。

对于此要求,我将在轮询模型中添加两个字段,这将加快sql查询。通常在这些情况下,选择比插入更频繁。因此,这将给您的项目带来更多的性能改进

from django.db import models


class Poll(models.Model):
    question = models.CharField(max_length=200, unique=True)
    num_censored_votes = models.PositiveIntegerField(default=0)
    num_uncensored_yes_votes = models.PositiveIntegerField(default=0)


class Vote(models.Model):
    poll = models.ForeignKey(Poll)
    accept = models.BooleanField()
    comment = models.CharField(max_length=200, unique=True)
    censored = models.BooleanField()

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        models.Model.save(self, force_insert, force_update, using, update_fields)
        poll = self.poll

        if self.censored:
            poll.num_censored_votes += 1
            poll.save()

        elif self.accept:
            poll.num_uncensored_yes_votes += 1
            poll.save()

这也可以使用信号来实现

我曾想过这样使用数据库,但希望避免这种情况。无论如何,这是最合理的解决办法。