Как эффективно использовать запрос Django и Q для фильтрации каждого объекта в наборе запросов и возврата 1 значения поля для каждого уникального поля в наборе запросов

У меня есть запрос, который возвращает следующий набор запросов:

results = <QuerySet [<Product: ItemA>, <Product: ItemA>, <Product: ItemB>, <Product: ItemB>, <Product: ItemB>, <Product: ItemC>, <Product: ItemC>]>

Представление модели __str__ - это name, и каждая вариация Product, вероятно, имеет различное значение для поля price. После этого запроса мне нужно найти в моей базе данных каждый Product в наборе запросов и вернуть самую низкую цену для каждого уникального name, например:

Lowest price for all in database where name is == to ItemA
Lowest price for all in database where name is == to ItemB
Lowest price for all in database where name is == to ItemC

Для достижения этой цели я использую следующий блок кода:

query_list = []
for each in results:
    if each.name not in query_list:   #Checks if the name of the object is not in in the query list
        query_list.append(each.name)   #Adds just the name of the objects so there is just one of each name in query_list

for each in query_list:
    priced = results.filter(name=each).order_by('price').first()  #Lowest price for each name in query_list

Это кажется очень неэффективным. Есть ли способ сделать подобное вычисление без необходимости добавлять уникальное имя каждого Product в отдельный список и повторять этот список, а затем делать запрос для каждого из них? Я чувствую, что есть способ использовать тип сложного поиска для достижения моих целей, возможно, событие использует меньше Python и заставляет db выполнять больше работы, но приведенное выше - лучшее, что я смог выяснить, поэтому далеко. В results может быть много разных совпадений, поэтому мне нужно, чтобы этот блок был максимально эффективным.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
134
1

Ответы 1

Это легко сделать после прочтения документации Создание агрегатов для каждого элемента в QuerySet, а также «Взаимодействие с упорядочиванием по умолчанию или order_by ()».

from django.db.models import Min

prices = {x['name']: x['lowest_price']
          for x in results.values('name').annotate(lowest_price=Min('price').order_by()}

for product in results:
    if product.name in prices and product.price == prices[product.name]:
        priced = row  # output the row
        del prices[product.name]

Это выполняется двумя запросами к базе данных.

Еще более эффективное решение с одним запросом, вероятно, возможно с Оконная функция, но для этого требуется расширенный бэкэнд базы данных, и он не может работать, например. в тестах с sqlite3.

Другие вопросы по теме