【问题标题】:Django aggregate queryset - combine the results of two querysets which both contain aggregatesDjango 聚合查询集 - 结合两个查询集的结果,这两个查询集都包含聚合
【发布时间】:2014-02-23 09:08:05
【问题描述】:

我在 django 中有以下模型:

action = models.CharField("Action performed",max_length=200,db_index=True)
    date = models.DateField("Date when event occured",blank=True)
    time = models.TimeField("Time when event occured",blank=True)
    timestamp = models.DateTimeField("Timestamp when event occured",blank=True,null=True,db_index=True)
    username = models.ForeignKey(USER)
    computer = models.ForeignKey(COMPUTER)
    location = models.ForeignKey(LOCATION)

我希望将数据返回到具有以下列的 HTML 页面:

COMPUTER NAME, COUNT(LOGON), COUNT(LOGOFF)

我正在使用

logOnOffData = LOGONOFF.objects.all()
computerBreakDown = logOnOffData.values("computer__computerName").annotate(Count("timestamp"))

这会生成数据库表中包含的每台计算机的出现次数。我可以轻松地为每个操作生成一个查询集,但看不到如何将两个查询集的结果合并到一个中。

【问题讨论】:

    标签: django django-models django-views django-queryset


    【解决方案1】:

    过滤注释会很棒,比如:

    loging_logut = ( Computer
                     .objects
                     .all()
                     .annotate( longons = Count( action__action = 'logon' ) )
                     .annotate( longouts = Count( action__action = 'logout' ) )
    

    但是这种语法在 django ORM 上是不允许的。您可以在FILTERING ON ANNOTATIONS IN DJANGO 帖子上了解它。

    在引用的文章中,您可以了解一些解决方法:例如writing your own sql code in extra field

    如果性能不是问题,那么代码可读性最高的方法是这样的字典:

    { 'john s computer': { 'n_logins': 100, 'n_logounts' :99 }, 
      'mathiew s computer': { 'n_logins': 80, 'n_logouts' :80 }, 
      ...
     }
    

    要获取此字典,您可以分别注释登录和注销,然后加入它:

    #logons = { 'john s computer': 100, 'mathiew s computer': 80, ... }
    logons = dict(
                   Computer
                   .objects
                   .filter( action__action = 'logon' )
                   .annotate( longons = Count(  ) )
                   .values_list( 'name', 'logons' )
             )
    
    #logons = { 'john s computer': 99, 'mathiew s computer': 80, ... }
    logouts = dict( ...
    
    #joining dicsts
    computers = {}
    for computer in Computer.objects.all().values_list( 'name', flat = True):
        computers[computer]['n_logins'] = logons[computer]
        computers[computer]['n_logouts'] = logouts[computer]
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 2020-04-27
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多