Когда выполняется Django Querysets в представлении?
Я прочитал документацию Querysets Django относительно ленивости querysets, но все еще немного запутался здесь.
В моем представлении, я устанавливаю queryset в переменную так
players = Players.objects.filter(team=team)
Позже у меня есть механизм сортировки, который я могу применить
sort = '-player_last_name'
if pts > 20:
players = players.filter(pts__gte = pts).order_by(sort)
else:
players = players.filter(pts__lte = pts).order_by(sort)
if ast < 5:
players = players.filter(asts__lte = ast).order_by(sort)
else:
players = players.filter(asts__gte = ast).order_by(sort)
context = {players: players)
return render(request, '2021-2022/allstars.html', context)
Я хочу знать, когда оценивается кверисет игроков? Это происходит при рендеринге каждой страницы или каждый раз, когда я присваиваю кверисет переменной? Потому что если это первое, тогда я могу просто применить цепочку .order_by(sort) и предыдущие приложения будут излишними.
QuerySet
оцениваются, если вы "потребили" кверисет. Вы потребляете кверисет путем перечисления над ним, вызывая .get(…)
, .exists(…)
, .aggregate(…)
или .count(…)
, проверить правдивость (например, с помощью if myqueryset:
или bool(queryset)
, или позвонить len(…)
по нему и т.д. Как правило, он оценивается, если вы выполняете над ним действие, результат которого больше не является QuerySet
.
Если вы перечисляете над ним или вызываете len(…)
результат кэшируется в QuerySet
, поэтому вызов его во второй раз или перечисление над ним после вызова len(…)
не будет совершать повторное обращение к базе данных.
В этом конкретном случае ни один из QuerySet
не оценивается до вызова функции render(…)
. Если в шаблоне вы, например, используете {% if players %}
, или {% for players %}
, {{ players|length }}
, или {{ players.exists }}
, то он будет оценивать кверисет.
Запросы в Django разработаны как "ленивые" - то есть, они не выполняют запрос к базе данных, пока что-то не запросит фактические данные. Запросы могут быть модифицированы добавлением фильтрации и других подобных функций.
Например, следующий код запрашивает все объекты TeamMember
, когда строка поиска равна 'all'
, но в противном случае добавляет фильтр, чтобы ограничить имена теми, которые соответствуют заданному поиску.
squad_list = TeamMember.objects(state__in={"Hired", "Joined", "Staff", "Recruiting"})
if squadname != 'all':
squad_list = squad_list(squad__icontains=squadname.lower())
Когда запрос squadlist
будет выполнен, он получит требуемую запись. Это поможет?