Фильтр Django order_by() с отдельными()
Как я могу сделать order_by
как это....
p = Product.objects.filter(vendornumber='403516006')\
.order_by('-created').distinct('vendor__name')
Проблема заключается в том, что у меня есть несколько поставщиков с одинаковым именем, и я хочу только самого последнего продукта от поставщика.
Надеюсь, что это имеет смысл?
Я получил ошибку DB:
Выражения SELECT DISTINCT ON должны соответствовать начальным выражениям ORDER BY LINE 1: SELECT DISTINCT ON ( "search_vendor". "Name" ) "Search_product"...
Ответы
Ответ 1
На основании вашего сообщения об ошибке и этот другой вопрос, мне кажется, это исправит его:
p = Product.objects.filter(vendornumber='403516006')\
.order_by('vendor__name', '-created').distinct('vendor__name')
Таким образом, кажется, что выражение (s) DISTINCT ON
должно соответствовать крайнему левому выражению ORDER BY
. Поэтому, создав столбец, который вы используете в distinct
в качестве первого столбца в order_by
, я думаю, что он должен работать.
Ответ 2
Просто совпадение leftmost order_by() arg и distinct() не работает для меня, создавая ту же ошибку (ошибка Django 1.8.7 или функция)?
qs.order_by('project').distinct('project')
однако он работал, когда я изменил на:
qs.order_by('project_id').distinct('project')
и у меня даже нет нескольких аргументов order_by.
Ответ 3
У меня была аналогичная проблема, но с соответствующими полями. Просто добавив связанное поле в distinct()
, я не получил правильные результаты.
Я хотел сортировать room__name
, сохраняя уникальный person
(связанный с residency
). Повторение связанного поля в соответствии с приведенной ниже проблемой:
.order_by('room__name', 'residency__person', ).distinct('room__name', 'residency__person')
См. также эти связанные сообщения:
Ответ 4
Если вы надеетесь использовать отдельное поле для отдельного поля и упорядочить по другому полю, вы можете использовать приведенный ниже код
from django.db.models import Subquery
Model.objects.filter(
pk__in=Subquery(
Model.objects.all().distinct('foo').values('pk')
)
).order_by('bar')