Выберите отдельные значения из поля таблицы

Я изо всех сил пытаюсь понять ORM Django. Я хочу получить список различных значений в поле в моей таблице ... эквивалент одного из следующих:

SELECT DISTINCT myfieldname FROM mytable

(или альтернативно)

SELECT myfieldname FROM mytable GROUP BY myfieldname

Я бы по крайней мере хотел сделать это способом Django, прежде чем прибегать к необработанному sql. Например, с таблицей:

id, улица, город

1, Main Street, Hull

2, Другая улица, Корпус

3, Bibble Way, Лестер

4, Другой путь, Лестер

5, Хай-стрит, Лондон

Я бы хотел получить:

Халл, Лестер, Лондидиум.


person alj    schedule 17.03.2010    source источник


Ответы (3)


Скажите, что ваша модель "Магазин"

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city',)

Поскольку у вас может быть установлен атрибут Meta class ordering (который является кортежем или списком), вы можете использовать order_by() без параметров, чтобы очистить любой порядок при использовании distinct(). См. Документацию в разделе order_by ()

Если вы не хотите, чтобы к запросу применялось какое-либо упорядочение, даже упорядочение по умолчанию, вызовите order_by () без параметров.

и distinct() в примечании, где обсуждаются проблемы с использованием distinct() с заказом.

Чтобы запросить вашу БД, вам просто нужно позвонить:

models.Shop.objects.order_by().values('city').distinct()

Он возвращает словарь

or

models.Shop.objects.order_by().values_list('city').distinct()

Этот возвращает ValuesListQuerySet, который можно преобразовать в list. Вы также можете добавить flat=True к values_list, чтобы сгладить результаты.

См. Также: Получение различных значений Queryset по полю

person jujule    schedule 18.03.2010
comment
На самом деле это работает. Тем не мение! Я не мог заставить его работать на всех моих моделях. Вейдли, это сработало на некоторых, но не на других. Для тех, у кого есть мета-порядок, это не работает. Итак, вам нужно сначала очистить порядок в наборе запросов. models.Shop.objects.order_by (). values ​​('city'). independent () - person alj; 18.03.2010
comment
Важно отметить, что values_list на самом деле не возвращает список. Он возвращает что-то вроде набора запросов. Я счел полезным всегда использовать list () вокруг вызовов values_list. - person dheerosaur; 19.11.2012
comment
values_list возвращает ValuesListQuerySet, который является итератором. Приведение к списку может быть удобно, но также может сказаться на производительности, когда все строки должны быть оценены одновременно, особенно с большими наборами данных. - person Peter Kilczuk; 27.11.2012
comment
Meta: ordering = () особенность django orm и objects.distinct() vs. objects.ordering().distinct() вызвали у нас многочасовое замешательство. На этом продукте должна быть наклейка с предупреждением о безопасности потребителей;) Мы можем ввести политику отсутствия мета-атрибутов, чтобы предотвратить появление царапин на голове в будущем. - person hobs; 20.02.2013
comment
Вы можете отключить Meta класс ordering и решить проблемы с distinct, используя order_by() без параметров. Он находится в документации API QuerySet в разделе order_by() < i> Если вы не хотите, чтобы к запросу применялось какое-либо упорядочение, даже упорядочение по умолчанию, вызовите order_by() без параметров. - person Mark Mikofski; 24.08.2014
comment
Я не уверен, почему на фото появился order_by. Вопрос был связан с получением четких значений, и это может быть достигнуто без какого-либо упорядочивания. Shop.objects.values ​​(myfieldname) .distinct () - person comiventor; 08.02.2018
comment
Первый вариант также возвращает набор запросов, так что это не совсем то, что нужно. - person JD Gamboa; 16.03.2019

В дополнение к все еще очень актуальному ответу юджуле, я считаю очень важным также знать о последствиях order_by() для distinct("field_name") запросов. Однако это только функция Postgres!

Если вы используете Postgres и определяете имя поля, для которого запрос должен отличаться, тогда order_by() необходимо начинать с того же имени поля (или имен полей) в той же последовательности (после этого может быть больше полей).

Примечание

Когда вы указываете имена полей, вы должны указать order_by () в QuerySet, а поля в order_by () должны начинаться с полей в independent () в том же порядке.

Например, SELECT DISTINCT ON (a) дает вам первую строку для каждого значения в столбце a. Если вы не укажете порядок, вы получите произвольную строку.

Если вы хотите с помощью e-g- извлечь список городов, в которых вы знаете магазины, пример джужуле должен быть адаптирован к этому:

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  
person ingofreyer    schedule 24.05.2018

По примеру:

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []
person Roger Sodré    schedule 06.08.2018