【问题标题】:Challenging Django queryset construction, filtering and sorting挑战 Django 查询集的构建、过滤和排序
【发布时间】:2015-11-17 13:41:58
【问题描述】:

我在 Django 中有一个网站,用户在其中创建聊天室,其他用户然后访问所述聊天室。这样的聊天室可以对公众开放,也可以对私人开放。简单的模型是:

class ChatRoom(models.Model):
    owner = models.ForeignKey(User)
    private = models.CharField(max_length=5, default=0)
    created_at = models.DateTimeField(auto_now_add=True)

class RoomTraffic(models.Model):
    visitor = models.ForeignKey(User)
    which_room = models.ForeignKey(ChatRoom)
    time = models.DateTimeField(db_index=True, auto_now_add=True)

如何获取所有公共聊天室 (chatroom.private='0') 的列表,按过去 60 分钟内看到的唯一身份访问者总数排序?那些没有看到太多(或任何)动作的聊天室将排在最后,那些动作最多的将排在最前面;将列出所有。


尝试了以下方法,但徒劳无功:

date = datetime.now()-timedelta(hours=1)
articles = ChatRoom.objects.filter(private='0').extra(select = {
  "views" : """
  SELECT COUNT(*)
  FROM myapp_roomtraffic
    JOIN myapp_chatroom on myapp_roomtraffic.which_room_id = myapp_chatroom.id
  WHERE myapp_roomtraffic.visitor_id = myapp_user.id
  AND myapp_roomtraffic.time > %s """ % date,
}).order_by("-views")

这个简单的返回错误:“00”或附近的语法错误(其中“00”是extra内部的日期时间对象)

【问题讨论】:

  • 这是我尝试过的,但徒劳无功:date = datetime.now()-timedelta(hours=1)rooms = ChatRoom.objects.filter(private='0').extra(select={'uniques':'SELECT COUNT (DISTINCT visitor_id) FROM myapp_chatroom AS roomtraffic WHERE (roomtraffic.time > %s AND roomtraffic.which_group_id=roomtraffic.which_group_id)'},select_params=(date,),).order_by('-uniques')
  • 这给了我一个:“SELECT”处或附近的语法错误(没有太多可继续的)
  • 为什么private 不是BooleanField
  • 是的,Kye,重写了它,它现在是一个布尔值。想试一试答案吗? :-)

标签: python django django-queryset


【解决方案1】:

您需要使用聚合功能。 (称为聚合和注释) 你可以在这里读到它。 https://docs.djangoproject.com/en/1.8/topics/db/aggregation/

主要思想是: 你不能把一些数据想象成一个虚拟字段,其中包含你在许多其他字段上收集(聚合)的数据,然后像其他字段一样使用该虚拟字段。

from django.db.models import Count

last_hour_delta = datetime.now()-timedelta(hours=1)

ChatRoom.objects.annotate(visitors_count=Count('room_traffic__visitor')).filter(private=False).filter(created_at__gt=last_hour_delta).order_by('-visitors_count')

附言我不测试这段代码。只是一个例子。

【讨论】:

  • 这会将非唯一身份访问者的总数添加到每个组,然后通过创建日期过滤组。那不是我想要的。我想按过去 1 小时内的唯一身份访问者总数对组进行排序(可以在过去的任何时间创建组)。
猜你喜欢
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 2018-06-13
  • 2012-04-15
  • 1970-01-01
相关资源
最近更新 更多