django-activity-stream с агрегацией
Я использую
django-activity-stream
создать ленту целей. Упрощенная версия объекта Goal выглядит следующим образом:
class Goal(models.Model):
user = models.ForeignKey(User, related_name="goals", on_delete=models.CASCADE)
liked_by = models.ManyToManyField(User, related_name="goals_cheered")
title = models.CharField(_("title"), max_length=80)
Есть два действия: цель должна появиться в ленте после ее создания и после ее выполнения. Тогда пользователям может понравиться цель, и вот где я застрял: добавление счетчика лайков в ленту.
Это была (неудачная) попытка, которая до сих пор имела для меня наибольший смысл:
from django.db.models import Prefetch
goal_qs = Goal.objects.annotate(likes=Count("liked_by"))
prefetch = [Prefetch("action_object", queryset=goal_qs)]
# in a `group` feed:
qs = group.target_actions.all().prefetch_related("actor__profile").prefetch_related(*prefetch)
Это дает мне
ValueError
: "Пользовательский набор запросов нельзя использовать для этого поиска." Может быть, это потому, что django-activity-stream использует GFK?
Как я могу подсчитать лайки? Можно как-то ограничить content_type?
Обновить
Удалось получить работу с помощью
{{ goal.liked_by.all|length }}
по шаблону. Не очень удобно с этим решением, особенно в ListView. Это казалось супер неоптимизированным.
1 ответ
Это действительно неоптимально. Но я боюсь, что с универсальными внешними ключами вы не сможете добиться большего. Тем не мение,
{{ goal.liked_by.count }}
все равно будет намного эффективнее, чем
{{ goal.liked_by.all|length }}
.