Получить разные значения Queryset по полю - PullRequest
44 голосов
/ 08 августа 2010

У меня есть эта модель:

class Visit(models.Model):
    timestamp  = models.DateTimeField(editable=False)
    ip_address = models.IPAddressField(editable=False)

Если пользователь посещает несколько раз в течение одного дня, как мне отфильтровать уникальные строки на основе поля ip? (я хочу уникальные посещения на сегодня)

today = datetime.datetime.today()
yesterday = datetime.datetime.today() - datetime.timedelta(days=1)

visits = Visit.objects.filter(timestamp__range=(yesterday, today)) #.something?

EDIT:

Я вижу, что могу использовать:

Visit.objects.filter(timestamp__range=(yesterday, today)).values('ip_address')

чтобы получить ValuesQuerySet только для полей ip. Теперь мой QuerySet выглядит так:

[{'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address':
 u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}]

Как мне отфильтровать это для уникальности, не оценивая QuerySet и не принимая удар по дб?

# Hope it's something like this...
values.distinct().count()

Ответы [ 2 ]

36 голосов
/ 08 августа 2010

То, что вы хотите:

Visit.objects.filter(stuff).values("ip_address").annotate(n=models.Count("pk"))

Для этого нужно получить все ip_addresses, а затем получить количество первичных ключей (или количество строк) для каждого IP-адреса.

16 голосов
/ 03 апреля 2012

С ответом Алекса у меня также есть n: 1 для каждого элемента. Даже с отдельным выражением ().

Это странно, потому что это возвращает хорошее количество предметов:

Visit.objects.filter(stuff).values("ip_address").distinct().count()

Но когда я перебираю "Visit.objects.filter (stuff) .values ​​(" ip_address "). Different ()", я получил гораздо больше элементов и несколько дубликатов ...

РЕДАКТИРОВАТЬ:

Предложение фильтра доставляло мне неприятности. Я фильтровал с другим полем таблицы, и был создан SQL JOIN, который ломал разные вещи. Я использовал эту подсказку, чтобы увидеть запрос, который действительно использовался:

q=Visit.objects.filter(myothertable__field=x).values("ip_address").distinct().count()
print q.query

Затем я обратился к классу, когда выполнял запрос, и к фильтру, чтобы иметь соединение, которое не зависит от идентификатора «Посещения».

надеюсь, это поможет

...