Я хочу взяти останні 10 екземплярів моделі і мати цей код:
Model.objects.all().order_by('-id')[:10]
Це правда, що спочатку підберіть всі екземпляри, а потім візьміть лише 10 останніх? Чи є якийсь більш ефективний метод?
Я хочу взяти останні 10 екземплярів моделі і мати цей код:
Model.objects.all().order_by('-id')[:10]
Це правда, що спочатку підберіть всі екземпляри, а потім візьміть лише 10 останніх? Чи є якийсь більш ефективний метод?
Відповіді:
Запити Джанго ледачі. Це означає, що запит потрапить у базу даних лише тоді, коли ви конкретно запитаєте результат.
Отже, поки ви не надрукуєте або фактично не використаєте результат запиту, ви можете додатково фільтрувати без доступу до бази даних.
Як ви бачите нижче, ваш код виконує лише один запит sql, щоб отримати лише останні 10 елементів.
In [19]: import logging
In [20]: l = logging.getLogger('django.db.backends')
In [21]: l.setLevel(logging.DEBUG)
In [22]: l.addHandler(logging.StreamHandler())
In [23]: User.objects.all().order_by('-id')[:10]
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]
Насправді я думаю, що LIMIT 10
це буде видано в базу даних, тому розрізання відбуватиметься не в Python, а в базі даних.
Додаткову інформацію див. У наборах обмежувальних запитів .
Схоже, рішення в питанні більше не працює з Django 1.7, і виникає помилка: "Неможливо впорядкувати запит, коли фрагмент був зроблений"
Відповідно до документації https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets, що примушує параметр "крок" синтаксису зрізу Python, оцінює Запит. Це працює так:
Model.objects.all().order_by('-id')[:10:1]
Ще мені цікаво, чи виконується ліміт у SQL або Python-фрагментах, весь масив результатів, що повертається. Немає користі для отримання величезних списків до пам'яті додатків.
Так. Якщо ви хочете отримати обмежений набір об'єктів, ви можете скористатися наведеним нижче кодом:
Приклад:
obj=emp.objects.all()[0:10]
Початок 0 необов’язковий, значить
obj=emp.objects.all()[:10]
Вищевказаний код повертає перші 10 екземплярів.
Як доповнення та зауваження до інших корисних відповідей, варто зауважити, що насправді виконання [:10]
нарізки поверне перші 10 елементів списку , а не останні 10 ...
Щоб отримати останні 10, вам слід зробити це [-10:]
замість цього (див. Тут ). Це допоможе вам уникнути використання order_by('-id')
з -
повністю змінити елементи.
Product.objects.filter(~Q(price=0))[-5:]
викликає у мене таку ж помилку: "Негативна індексація не підтримується."