#django #django-queryset #deprecated #django-3.1
Вопрос:
Я работаю над проектом, который только что перешел на django 3.1. И мне нужно удалить использование этой «передачи псевдонимов необработанных столбцов в QuerySet.order_by ()». Однако я не уверен, использует ли его мой проект. Поэтому мне нужно понять, как на самом деле работает «передача псевдонимов необработанных столбцов в QuerySet.order_by ()», если бы кто-нибудь мог предоставить мне пример кода, который передает псевдонимы необработанных столбцов в QuerySet.order_by (), это было бы действительно полезно и ценно.
Ответ №1:
tl;dr:
- запросы, которые используют синтаксис с разделителями точек для ссылок на таблицы и столбцы, следует изменить
- запросы, в которых используются
__
ссылки с разделителями на таблицы и столбцы, хороши как есть
Обнаружение устаревших версий во время выполнения
Ну, во-первых, самый простой способ обнаружить использование устаревших шаблонов-это запустить свой проект и/или набор тестов с PYTHONWARNINGS=always
помощью или python -Wd
. Если вы сделаете это, вы увидите несколько полезных предупреждений, которые могут выделить точные линии, в которых живет плохой шаблон.
Например, предупреждение, которое появляется при запуске моего примера кода с Django 3.1:
RemovedInDjango40Warning: Passing column raw column aliases to order_by() is deprecated. Wrap '-auth_user_groups.id' in a RawSQL expression before passing it to order_by().
User.objects.filter(groups__name='teachers').order_by('-auth_user_groups.id')
Пример — исправление неправильного запроса
Рассмотрим ниже — есть два запроса, каждый из которых будет упорядочивать учителей по срокам службы:
from django.contrib.auth.models import User
from django.db.models.expressions import RawSQL
# Deprecated!
# The value passed to `order_by` references a column on a table
User.objects.filter(groups__name='teachers').order_by('-auth_user_groups.id')
# Safe! We're now using RawSQL to make that same reference.
User.objects.filter(groups__name='teachers').order_by(
RawSQL('auth_user_groups.id', tuple()).desc()
)
Эти два запроса эквивалентны и переводятся на (сокращенный) SQL:
SELECT auth_user.*
FROM auth_user
INNER JOIN auth_user_groups ON auth_user.id = auth_user_groups.user_id
INNER JOIN auth_group ON auth_user_groups.group_id = auth_group.id
WHERE auth_group.name = 'teachers'
ORDER BY auth_user_groups.id DESC
Пример — незатронутые запросы
Однако большинство запросов не ссылаются на имена таблиц и столбцов с синтаксисом, разделенным точками.
Эти запросы просто прекрасны, и их не нужно изменять:
from django.contrib.auth.models import User
from django.db.models.expressions import RawSQL
# Safe - we're ordering by `auth_user.date_joined`
User.objects.order_by('date_joined')
# Safe - we're ordering by `auth_group.name` after a JOIN on auth_group
User.objects.order_by('groups__name')