Get distinct values of Queryset by field

Scott picture Scott · Aug 8, 2010 · Viewed 71k times · Source

I've got this model:

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

If a user visits multiple times in one day, how can I filter for unique rows based on the ip field? (I want the unique visits for today)

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

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

EDIT:

I see that I can use:

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

to get a ValuesQuerySet of just the ip fields. Now my QuerySet looks like this:

[{'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'}]

How do I filter this for uniqueness without evaluating the QuerySet and taking the db hit?

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

Answer

Alex Gaynor picture Alex Gaynor · Aug 8, 2010

What you want is:

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

What this does is get all ip_addresses and then it gets the count of primary keys (aka number of rows) for each ip address.