按字段获取Queryset的不同值

时间:2010-08-08 00:56:50

标签: django field distinct django-queryset

我有这个型号:

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

如果用户在一天内多次访问, 如何根据ip字段过滤唯一行? (我希望今天进行独特的访问)< / p>

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

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

修改

我看到我可以使用:

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

获取只有ip字段的ValuesQuerySet。现在我的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()

3 个答案:

答案 0 :(得分:36)

你想要的是:

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

这样做是获取所有ip_addresses,然后获取每个ip地址的主键数(也就是行数)。

答案 1 :(得分:16)

使用Alex答案我也为每个项目提供n:1。即使有distinct()子句。

这很奇怪,因为这会返回大量的项目:

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

但是当我迭代“Visit.objects.filter(stuff).values(”ip_address“)。distinct()”我得到了更多的东西和一些重复的东西......

编辑:

过滤条款给我带来了麻烦。我正在使用另一个表字段进行过滤,并且创建了一个SQL JOIN来打破这些不同的东西。 我用这个提示来查看真正使用的查询:

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

然后我将这个类恢复为女巫我正在进行查询,过滤器有一个不依赖任何“访问”ID的连接。

希望这会有所帮助

答案 2 :(得分:2)

问题与标题所暗示的不同。如果要从数据库中获得类似集合的行为,则需要类似这样的东西。

x = Visit.objects.all().values_list('ip_address', flat=True).distinct()

它应该给x这样的东西。

[1.2.3.4, 2.3.4.5, ...]

哪里

len(x) == len(set(x))

返回True