Родственная модель
class AbstractTask(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
issued_at = models.DateTimeField(auto_now_add=True)
Проблема
Мне нужно показывать статистику User
в день в админ-панели. Допустим, мне просто нужно количество выданных заданий. И мне нужно иметь возможность фильтровать его по дате выпуска (сколько было выпущено вчера, позавчера, и т. Д. c).
Как я пытаюсь это сделать
I используйте 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, без особых волхвов c и с продолжением использования DateFieldListFilter. Но любое решение поможет.