Django, эквивалентный для последней записи для каждого пользователя

Я удивлен, что этот вопрос не подошел. Не удалось найти много в сети.

Используя Entry.objects.latest('created_at') Я могу восстановить последнюю запись для всех объектов Записи, но сказать, хочу ли я последнюю запись для каждого пользователя? Это - что-то подобное SQL последний рекордный запрос. Но как я достигаю этого использования ORM? Вот мой подход, я задаюсь вопросом - ли это самый эффективный способ сделать то, что я хочу.

Сначала я выполняю запрос sub: Объекты сгруппированы пользователем и Max (последнее) created_by поле возвращается для каждого пользователя (created_at __ макс.), я затем фильтрую объекты Записи на основе результатов в подзапросе и получаю требуемые объекты.

Entry.objects.filter(created_at__in=Entry.objects.values('user').annotate(Max('created_at')).values_list('created_at__max'))

или использование менеджера:

class UsersLatest(models.Manager):  

    def get_query_set(self):
        return super(UsersLatest,self).get_query_set().filter(created_at__in=self.model.objects.values('user').annotate(Max('created_at')).values_list('created_at__max'))

Существует ли более эффективный путь? возможно без запроса sub?

Спасибо,

Paul

13
задан Carl Meyer 5 April 2010 в 12:30
поделиться

3 ответа

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

-1
ответ дан 2 December 2019 в 02:05
поделиться

Необработанный SQL будет иметь вид

SELECT entry.id, entry.title, entry.content, entry.user_id, entry.created_at
FROM
    entry
WHERE
    entry.created_at = ( SELECT Max(e2.created_at) from entry as e2 where e2.user_id = entry.user_id )

Таким образом, одним из вариантов является использование аргумента , где аргумента extra () модификатор :

Entry.objects.extra(where='entry.created_at = ( SELECT Max(e2.created_at) from entry as e2 where e2.user_id = entry.user_id )')

Конечно, вам, вероятно, придется изменить запись на любое фактическое имя таблицы в базе данных. Предполагая, что вам удобно просматривать ._ meta , вы можете попробовать следующее:

Entry.objects.extra( where=
    '%(table)s.created_at = ( SELECT Max(e2.created_at) from %(table)s as e2 where e2.user_id = %(table)s.user_id )' % { 'table':Entry._meta.db_table }
)

Вероятно, есть более элегантный способ получить имя таблицы.

1
ответ дан 2 December 2019 в 02:05
поделиться

Да, в списке рассылки разработчиков Emacs ведется долгое обсуждение интеграции диспетчера пакетов package.el в следующий основной выпуск Emacs: Интеграция package.el . Он автоматически загружает и устанавливает пакеты из ELPA (архив пакетов Emacs Lisp . Прочтите страницу установки , чтобы получить последнюю версию.

-121 --- 3909407] -

Дизайн вашего QuerySet зависит от того, для чего вы планируете его использовать. Я не уверен, почему вы выходите из итератора QuerySet с помощью метода values_list в конце. Полагаю, у вас есть список состояний пользователей, для которых вы показываете время последней активности на основе этой модели Entries. Для этого вы можете попробовать следующее:

Users.objects.all().annotate(latest_activity=Max('entries__created_at'))

А затем легко прокрутите список пользователей в своем шаблоне с помощью

{% for user in users %}
{{ user.full_name }}
{{ user.latest_activity|date: "m/d/Y" }}
{% endfor %}
1
ответ дан 2 December 2019 в 02:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: