5

所以我有一组可以出现在许多类别中的任务:

class TaskGroup(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    icon = models.CharField(max_length=200, blank=True, null=True)

    def __unicode__(self):
        return unicode(self.name)


class Task(models.Model):
    start_date = models.DateField()
    end_date = models.DateField()
    is_date_fuzzy = models.BooleanField()
    name = models.CharField(max_length=200)
    assignee = models.ForeignKey(User, verbose_name="users who is assigned the task", blank=True, null=True)
    task_groups = models.ManyToManyField(TaskGroup)

如您所见,每个任务都可以出现在多个任务组中。

我希望我的查询满足以下条件:

  1. 应返回所有任务组的列表。
  2. 特定组内任务数的计数。即家具(3),床上用品(2),落地灯(6)
  3. 如果特定任务组没有任务,则该组应该有 0
  4. 每个组内的任务由当前用户限制。

到目前为止,我想出的最好的是这样的:

TaskGroup.objects.filter(
    task__assignee=current_usr
).annotate(
    task_count=Count('task__id')
).order_by('name')

但它会在进行计数之前过滤所有内容,因此我看不到任务组为零的任务组。

也许我很想,但我多年来一直在尝试这样做,而我在这个阶段只是想循环并自己数数。

我真的希望你能帮助拯救我的理智所剩无几!

4

1 回答 1

0

我曾经遇到过完全相同的问题。一种解决方案是使用额外的子查询:

TaskGroup.objects.extra(
    select={"task_count": "SELECT COUNT(*) from app_task where app_task.id=app_taskgroup.task_id AND app_task.assignee = '?'"},
    select_params = [current_usr]
).order_by('name')

或类似的东西。可能加入密钥是错误的。

但这只是丑陋的。并打破了许多 DRY 和 DB 独立原则。

更好的选择可能是使用 2 个查询。第二个用于没有分配给该用户的任何任务的特定组:

empty_groups = TaskGroup.objects.exclude(task__assignee=current_usr)

然后只需迭代两组而不是仅一组。

于 2011-06-22T23:31:31.487 回答