django-уведомление: сколько наблюдаемых предметов
В данный момент у меня есть набор запросов, который возвращает количество элементов в модели, упорядоченных по количеству людей, которые смотрят его. Итак, у меня есть поле m2m, представляющее эту ссылку.
То есть:
#models.py
class MyModel(models.Model):
...
watchers = models.ManyToManyField(User, blank=True)
Я бы посчитал количество вхождений и упорядочил их по количеству в менеджере по умолчанию, который затем использовался представлением.
Теперь я перехожу к использованию django-уведомлений, используя "tification.ObservedItem ", чтобы позволить пользователям просматривать экземпляр MyModel.
Поэтому, на мой взгляд, когда пользователь публикует некоторый контент, у меня есть что-то вроде этого:
notification.observe(object, request.user, 'new_object')
Это хорошо работает.
Теперь, как я могу сгенерировать набор запросов, представляющий все объекты класса MyModel, упорядоченные по количеству людей, "наблюдающих" за ними?
2 ответа
Вы можете сделать это, используя аннотации:
from django.db.models import Count
MyModel.objects.annotate(num_users=Count('watchers')).order_by('num_users')
Проблема в том, что django-уведомление использует общие внешние ключи.
Итак, я переопределил поле моего наблюдателя:
watchers = generic.GenericRelation(notification.ObservedItem)
Затем я могу получить все наблюдатели для конкретного экземпляра MyModel.
$x = MyModel.objects.get(id=1)
$x.watchers.all()
$[<ObservedItem: ObservedItem object>, <ObservedItem: ObservedItem object>, <ObservedItem: ObservedItem object>]
$x.watchers.count()
$3
Близко, но не сигара. Я хотел сделать что-то вроде этого:
MyModel.objects.annotate(count=Count('watchers')).order_by('count')
Это то, что Джанго не может сделать, согласно документам.
API агрегирования базы данных Django не работает с GenericRelation.
Не волнуйтесь, я думаю, что это, вероятно, поможет:
http://charlesleifer.com/blog/generating-aggregate-data-across-generic-relations/
Репо здесь:
https://github.com/coleifer/django-generic-aggregation
Я еще не пробовал...