如何在用户的django管理面板中具有相关字段上的日期过滤器的统计信息?

问题描述 投票:1回答:1

相关型号

class AbstractTask(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    issued_at = models.DateTimeField(auto_now_add=True)

问题

我每天需要在管理面板上显示一些User统计信息。可以说仅是为用户发布的任务数,并且我需要能够按发布日期(昨天,前天等发布了多少)进行筛选。

我该怎么做

我使用User代理模型为不同的统计页面注册ModelAdmin

我在DateFieldListFilter字段上使用了稍加修改的日期范围task__issued_at

list_filter = [
    ('task__issued_at', DateFieldListFilter),
    'username',
]

日期过滤器不起作用

过滤器不起作用,因为它们最终会生成类似于以下内容的查询:

(queryset = User.objects
    .annotate(
        # Different statistics.
        num_tasks=Count('task'),
    )
    .filter(
        # DateFieldListFilter.
        task__issued_at__gte='2020-01-01',
        task__issued_at__lt='2020-01-02,
    )
    .values('id', 'num_tasks')
)

SQL:

SELECT "auth_user"."id",
       COUNT("task"."id") AS "num_tasks"
FROM "auth_user"
LEFT OUTER JOIN "task" ON ("auth_user"."id" = "task"."user_id")
INNER JOIN "task" T3 ON ("auth_user"."id" = T3."user_id")
WHERE (T3."issued_at" >= 2020-01-01 00:00:00+03:00
       AND T3."issued_at" < 2020-01-02 00:00:00+03:00)
GROUP BY "auth_user"."id"

问题是,当我只需要一个过滤器时,过滤器就会在表“任务”上添加第二个联接。

通过添加.filter(task__isnull=False)强制进行第一次内部联接无济于事。它只是继续执行两个相同的内部联接。

在django 2和3中是相同的行为。

可以在Django中完成吗?最好尽可能简单:没有原始sql,没有太多魔力,并继续使用DateFieldListFilter。但是任何解决方案都会有所帮助。

相关模型类AbstractTask(models.Model):user = models.ForeignKey(User,on_delete = models.CASCADE)issue_at = models.DateTimeField(auto_now_add = True)问题我需要显示一些User ...

django django-admin django-filter django-admin-filters
1个回答
0
投票

下面的替代QuerySet给出了相同的结果,没有任何其他joins

© www.soinside.com 2019 - 2024. All rights reserved.