按字段获取Queryset的不同值

Sco*_*ott 48 django field distinct django-queryset

我有这个型号:

class Visit(models.Model):
    timestamp  = models.DateTimeField(editable=False)
    ip_address = models.IPAddressField(editable=False)
Run Code Online (Sandbox Code Playgroud)

如果用户在一天内多次访问,如何根据ip字段筛选唯一行?(我想今天的独特访问)

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

visits = Visit.objects.filter(timestamp__range=(yesterday, today)) #.something?
Run Code Online (Sandbox Code Playgroud)

编辑:

我看到我可以使用:

Visit.objects.filter(timestamp__range=(yesterday, today)).values('ip_address')
Run Code Online (Sandbox Code Playgroud)

获取只有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'}]
Run Code Online (Sandbox Code Playgroud)

如何在不评估QuerySet和获取数据库命中的情况下过滤此唯一性?

# Hope it's something like this...
values.distinct().count()
Run Code Online (Sandbox Code Playgroud)

Ale*_*nor 41

你想要的是:

Visit.objects.filter(stuff).values("ip_address").annotate(n=models.Count("pk"))
Run Code Online (Sandbox Code Playgroud)

这样做是获取所有ip_addresses然后它获取每个IP地址的主键(也称为行数)的计数.

  • 问题可能是Meta.ordering - 尝试这个`Visit.objects.filter(stuff).order_by().values("ip_address").annotate(n = models.Count("pk"))` (7认同)
  • 我不认为我完全理解注释.在你编写它时,我的ValuesQuerySet现在有"n":1附加到每个条目.我不确定那是什么告诉我的? (2认同)
  • @Greg 谢谢!我新发现 `ordering` 和 `order_by()` 会导致 `distinct` 出现问题,但我不知道如何解决它 - 尽管它在 [`order_by()`](https:/ /docs.djangoproject.com/en/dev/ref/models/querysets/#order-by) "_如果您不希望将任何排序应用于查询,甚至不是默认排序,请调用`order_by()`没有参数。_” (2认同)

Gui*_*dre 20

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

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

Visit.objects.filter(stuff).values("ip_address").distinct().count()
Run Code Online (Sandbox Code Playgroud)

但是,当我迭代"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
Run Code Online (Sandbox Code Playgroud)

然后我恢复了关于女巫的课我正在进行查询,过滤器有一个不依赖任何"访问"ID的连接.

希望这可以帮助


Chr*_*lan 8

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

x = Visit.objects.all().values_list('ip_address', flat=True).distinct()
Run Code Online (Sandbox Code Playgroud)

它应该给你类似这样的东西x

[1.2.3.4, 2.3.4.5, ...]
Run Code Online (Sandbox Code Playgroud)

在哪里

len(x) == len(set(x))
Run Code Online (Sandbox Code Playgroud)

退货True