django-notification: сколько наблюдаемых элементов

На данный момент у меня есть набор запросов, который возвращает количество элементов в модели, упорядоченное по количеству людей, которые ее смотрят. Итак, у меня есть поле m2m, представляющее эту ссылку.

Ie:

#models.py
class MyModel(models.Model):
...
watchers = models.ManyToManyField(User, blank=True)

Я бы подсчитал количество вхождений и упорядочил их по количеству в диспетчере по умолчанию, который затем использовался представлением.

Теперь я перехожу к использованию django-notification, используя 'notification.ObservedItem', чтобы разрешить пользователям смотреть экземпляр, если MyModel.

Итак, на мой взгляд, когда пользователь публикует некоторый контент, у меня получается что-то вроде этого:

notification.observe(object, request.user, 'new_object')

Это хорошо работает.

Теперь, как я могу сгенерировать набор запросов, представляющий все объекты класса MyModel, упорядоченные по количеству людей, «наблюдающих» за ними?


person powlo    schedule 27.07.2012    source источник


Ответы (2)


Вы можете сделать это, используя аннотации:

from django.db.models import Count
MyModel.objects.annotate(num_users=Count('watchers')).order_by('num_users')
person Gonzalo    schedule 27.07.2012
comment
Вы правы, я думаю, что вместо этого аннотация должна быть на MyModel, редактируя ответ. - person Gonzalo; 27.07.2012
comment
Святой дым, ты прав. Я смущен, почему в документации сказано, что вы не можете этого сделать, когда кажется, что можете. - person powlo; 27.07.2012
comment
FWIW, я протестировал свой код с вашей первой реализацией модели (наблюдатели были M2M) и работал хорошо :) - person Gonzalo; 27.07.2012
comment
Да, у меня он работал со стандартным m2m, но это было до перехода на django-notification. - person powlo; 27.07.2012
comment
А, не знал, что ты удалил m2m. В этом случае, я думаю, у вас есть два варианта: вернуть m2m и прикрепить обработчик сигнала к «наблюдать», который добавляет к нему экземпляр пользователя, или попробовать django-generic-aggregation. - person Gonzalo; 27.07.2012

Проблема в том, что django-notification использует общие внешние ключи.

Итак, я переопределил поле наблюдателей:

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')

Это то, чего не может Django, согласно документам.

API агрегации базы данных Django не работает с GenericRelation.

Не волнуйтесь, я думаю, что это, вероятно, поможет:

http://charlesleifer.com/blog/generating-aggregate-data-across-generic-relations/

Репо здесь:

https://github.com/coleifer/django-generic-aggregation

я еще не пробовала...

person powlo    schedule 27.07.2012