Цель
Запрос всех продуктов, нарезка их на части, возвращение подмножества этих продуктов с добавлением key:value
, другими словами, обогащенного.
Код, который работает, но я не могу использовать
Я не могу использовать этот код, потому что я использую paginator, paginator получает доступ к count
из QuerySet
.Если я передам нарезанный QuerySet , то это число будет только для этой нарезанной части, а не для общего QuerySet
, поэтому я не могу его использовать.
products_qs = final_qs[paginator.get_offset(request):
paginator.get_offset(request) + paginator.get_limit(request)]
for product in products_qs:
product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)
Это прекрасно работает, когда я печатаю данные, я вижу, что super_cool_new_key
обогащение в каждом продукте.Потрясающие.Проблема?Ну, мне пришлось нарезать его, и теперь метод count больше не верен.Конечно, я могу сделать что-то вроде:
products_qs.count = final_qs.count
и продолжить свою жизнь, но это кажется ... хаком, а может и нет?
Код, который я хотел бычтобы он работал, но не
for i in range(paginator.get_offset(request),
paginator.get_offset(request) + paginator.get_limit(request)):
product = final_qs[i]
product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)
Когда я вижу вывод данных, super_cool_new_key
там нет.Я не могу понять, почему?
Возможно, у меня тяжелый день, и я не понимаю, как получить доступ по ссылке, поэтому я удаляю среднюю обезьяну.
final_qs = final_qs.all()
for i in range(paginator.get_offset(request),
paginator.get_offset(request) + paginator.get_limit(request)):
final_qs[i].raw['super_cool_new_key'] = ms_response.get('results').get(final_qs[i].id, '')
Подозрения
Очевидно, что разница в коде заключается в том, что один из способов работает, а другой - нет.Мой доллар следующий:
Просмотр Django Docs для QuerySet :
Итерация.QuerySet является итеративным, и он выполняет свой запрос к базе данных при первой итерации по нему.
Затем о нарезке:
Slicing.Как объясняется в разделе Ограничение QuerySets, QuerySet может быть нарезан с использованием синтаксиса Python для нарезки массивов.Нарезка неоцененного QuerySet обычно возвращает другой неоцененный QuerySet, но Django выполнит запрос к базе данных, если вы используете параметр «step» синтаксиса слайса, и вернет список
Я не могу быть нарезкойтогда, потому что я не делаю срез с параметром "шаг".Поскольку он возвращает неоцененный QuerySet код, который я хочу работать, теоретически должен работать.(Разве это не всегда так? Ха-ха)
Хорошо, так что проясняется тот факт, что, когда в первом варианте кодирования я выполнил итерацию for x in x_container
, QuerySet
был выполнен.Может ли это быть ответом?Поэтому я изменил код:
Оповещение о спойлере: все еще не работает
final_qs = final_qs.all()
for i in range(paginator.get_offset(request),
paginator.get_offset(request) + paginator.get_limit(request)):
product = final_qs[i]
product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)
Эммм ... помогите?
Aпредложил ответ, что, спойлер оповещения, не работал
from django.db.models import When, Case, Value, CharField
when = [ When(id=k, then=Value(v)) for k,v in ms_response.get('results').items()]
p = final_qs[paginator.get_offset(request)
:paginator.get_offset(request) + paginator.get_limit(request)]
p = p.annotate(super_cool_new_key=Case(
*when,
default=Value(''),
output_field=CharField()
)
)
Я также пробовал без нарезки , но с .all().annotate()
.Все еще не работал.Это не работает, не из-за возникновения Исключения, а потому, что когда я вижу вывод, этого super_cool_new_key
нет, то есть он не обогатил объекты, а в этом весь смысл.