如何使用注释对 Django QuerySet 中的项目进行计数

How to use annotate to Count items from a Django QuerySet

我正在对应用程序及其在用户设备上的安装方式进行建模,如下所示:

class WindowsUserApplications(models.Model):
    application_name = models.CharField(max_length=60, null=False, unique=True)
    category = models.ForeignKey('ApplicationCategory', null=False, default=10, on_delete=models.SET_DEFAULT)

class WindowsUserInstalls(models.Model):
    device_name = models.CharField(max_length=15, null=False)
    version = models.CharField(max_length=30, null=False)
    application = models.ForeignKey('WindowsUserApplications', related_name='windows_user_applications', null=False, on_delete=models.CASCADE)

然后,在视图中我想获取已安装应用程序的列表,如下所示:

def user_inventory(request, *args, **kwargs):
    user_applications = WindowsUserInstalls.objects.annotate(Count('application'))
    template = 'webapp/user_inventory.html'
    context = {
        'user_applications' : user_applications,
    }
    return render(request, template, context)

但是,对于已安装的应用程序和所有安装计数为 1 的应用程序,我总是收到重复的行,而不是对它们进行汇总。

我尝试了其他方法,例如将 .values('application') 添加到查询中,但没有成功。

提前感谢您的任何提示。

我找到了一种方法(我不确定这是否是最佳方法)来获取视图中我需要的所有字段。

def user_inventory(request, *args, **kwargs):
    user_applications = WindowsUserInstalls.objects.select_related(
            'application', 'category'
        ).values(
            'application', 'application__application_name', 'application__category__name'
        ).annotate(
            Count('application')
        )
    template = 'webapp/user_inventory.html'
    context = {
        'user_applications': user_applications,
    }
    return render(request, template, context)

诀窍是添加 .select_related('application', 'category') 调用以从通过外键相关的其他表中获取值,以及添加 .values() 调用以获取我需要的值,包括那些是来自相关表:application__application_nameapplication__category_name。注意双下划线。

多亏了这一点,annotate(Count('application')) 才真正起作用,我可以像这样在模板中获取值:

{% for application in user_applications %}
    <tr>
        <td>{{ application.application }}</td>
        <td>{{ application.application__application_name }}</td>
        <td>{{ application.application__count }}</a></td>
        <td>{{ application.application__category__name }}</a></td>
    </tr>
{% endfor %}

如果有更好的方法,请务必告诉我。