Создание вспомогательной функции для безопасного извлечения «главного» элемент из любого набора запросов. Я использую все это в своих приложениях Django.
def top_or_none(queryset):
"""Safely pulls off the top element in a queryset"""
# Extracts a single element collection w/ top item
result = queryset[0:1]
# Return that element or None if there weren't any matches
return result[0] if result else None
Это использует немного трюк ж/slice operator to add a limit clause onto your SQL.
Теперь эта функция используется везде, где вам нужно получить «верхний» элемент набора запросов. В этом случае, вы хотите, чтобы получить верхний элемент B для данного А где Б сортируются по убыванию рк, как таковой:
latest = top_or_none(B.objects.filter(a=my_a).order_by('-pk'))
Там также недавно добавлена функция «Max» в Django Aggregation, которые могли бы помочь вам получить max pk, но в этом случае мне не нравится это решение, так как оно добавляет сложности.
P.S. Мне не очень нравится полагаться на поле «pk» для этого типа запросов, поскольку некоторые РСУБД не гарантируют, что последовательные pks совпадают с порядком логического создания. Если у меня есть таблица, которую я знаю, мне нужно будет запросить таким образом, у меня обычно есть свой собственный столбец datetime для создания, который я могу использовать для заказа вместо pk.
Редактировать на основе комментариев:
Если вы не хотите использовать QuerySet [0], вы можете изменить функцию 'top_or_none' Thusly:
def top_or_none(queryset):
"""Safely pulls off the top element in a queryset"""
try:
return queryset[0]
except IndexError:
return None
Я не предлагал этого изначально потому что у меня создалось впечатление, что queryset [0] отбросит весь набор результатов, а затем возьмет 0-й элемент. По-видимому, Django добавляет «LIMIT 1» в этом сценарии, поэтому это безопасная альтернатива моей нарезной версии.
Edit 2
Конечно, вы также можете воспользоваться соответствующим менеджером Джанго построить здесь и построить QuerySet через «А» объект, в зависимости от ваших предпочтений:
latest = top_or_none(my_a.b_set.order_by('-pk'))
Что такого разница между result = queryset [0: 1] и result = queryset [0]? – hekevintran
queryset [0: 1] будет возвращать пустой список, если нет соответствующих элементов, тогда как queryset [0] будет вызывать IndexError. –
Спасибо за ответ! – hekevintran