Выберите отдельные значения из поля таблицы - PullRequest
82 голосов
/ 18 марта 2010

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

SELECT DISTINCT myfieldname FROM mytable

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

SELECT myfieldname FROM mytable GROUP BY myfieldname

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

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

1, Main Street, Hull

2, Другая улица, Халл

3, Bibble Way, Лестер

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

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

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

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

Ответы [ 3 ]

171 голосов
/ 18 марта 2010

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

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()

Возвращает словарь

или

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

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

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

4 голосов
/ 24 мая 2018

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

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

Примечание

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

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

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

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  
2 голосов
/ 06 августа 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 []
...