【问题标题】:Get distinct values of Queryset by field按字段获取 Queryset 的不同值
【发布时间】:2011-03-26 20:24:00
【问题描述】:

我有这个模型:

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?

编辑:

我知道我可以使用:

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

【问题讨论】:

标签: django field distinct django-queryset


【解决方案1】:

你想要的是:

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

它的作用是获取所有 ip_addresses,然后获取每个 ip 地址的主键计数(也就是行数)。

【讨论】:

  • 我不认为我完全理解注释。正如您所写,我的 ValuesQuerySet 现在已将“n”:1 附加到每个条目。我不确定这告诉我什么?
  • 问题可能是 Meta.ordering - 试试这个Visit.objects.filter(stuff).order_by().values("ip_address").annotate(n=models.Count("pk"))
  • @Greg 谢谢!我知道orderingorder_by() 会导致distinct 出现问题,但我不知道如何解决它——尽管它在order_by() 下的QuerySet API 文档中“如果你不想任何要应用于查询的排序,甚至不是默认排序,都调用order_by(),不带参数。"
  • 在这种情况下pk 是什么?
  • pk - 主键。每条记录的唯一标识符。
【解决方案2】:

对于 Alex Answer,我还为每个项目提供了 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 的连接。

希望对你有帮助

【讨论】:

  • 这是一个问题还是一个答案?
  • 这是对亚历克斯答案的一种补充。我试过了,和vfxcode有同样的问题,然后我找到了原因。所以我想我应该分享我的发现。 3 年后,我承认我的回答有点混乱,我明白你为什么问这个;)
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2022-11-30
    • 2010-10-03
    • 2012-07-08
    • 2020-02-13
    • 1970-01-01
    • 2020-11-29
    • 2019-03-25
    • 1970-01-01
    • 2019-04-06
    相关资源
    最近更新 更多