сортировка набора запросов после цикла for - PullRequest
0 голосов
/ 23 октября 2019

Я хочу применить метод ко всем объектам в наборе запросов, а затем отсортировать их.

products = Product.objects.all()
for product in products:
    product.update_exist_flag()

products = products.order_by('-exist_flag')

возникает эта ошибка:

AssertionError: Невозможно переупорядочить запрос после получения фрагмента.

как я могу это исправить

Ответы [ 2 ]

3 голосов
/ 23 октября 2019

Возможно, вы захотите прочитать: Когда оцениваются QuerySets .

for product in products:: здесь запрос gets evaluated, т. Е. Данные находятся вне базы данных. После этого вы не сможете изменить порядок запроса.


В идеале вам следует повторить тот же запрос:

products = Product.objects.all()

for product in products:
    product.update_exist_flag()

products = Product.objects.all().order_by('-exist_flag')

Однако есть один трюк, чтобы сделать это, не выполняя тот же запрос снова (не касаясь базы данных):

products = Product.objects.all()

for product in products:
    product.update_exist_flag()

# This will return a list.
products = sorted(products, key=lambda p: p.exist_flag, reverse=True)    

Как упомянуто в комментарии @heemayl, если exist_flag является связанным объектом(запись в таблице в базе данных), затем он снова попадет в базу данных. В этом случае все же возможна одна оптимизация: if, которую вы хотите отсортировать на основе id в существующем_флаге, тогда мы можем использовать p.exist_flag_id вместо p.exist_flag, чтобы она не попала в базу данных.

0 голосов
/ 23 октября 2019

Выполните запрос еще раз:

products = Product.objects.all()
for product in products:
    product.update_exist_flag()

products = Product.objects.all().order_by('-exist_flag')

Как правило, всякий раз, когда вы хотите выполнить какую-либо операцию с моделями, выполняйте ее на уровне базы данных, это будет быстрее, чем ее выполнение на уровне Python.

...