复杂的Django ORM注释和聚合

问题描述

我目前正在将一些记录的项目准备为JSON序列化格式。

我正尝试通过Django的内置ORM,利用注释和聚合来实现此目的。

我正在尝试针对每个“记录的项目”复制以下结构:

...
{
    "count": 20,"metric-type": "total-dataset-requests","access-method": "regular","country-counts": {
        "au": 6,"jp": 1,"us": 13
    }
}
...

我目前是根据我自己的知识构建的queryset

metrics = LoggedItem.objects.filter(
    identifier=record['identifier'],hit_type='investigations',is_machine=False,is_robot=False
).values(
    'identifier','country'
).annotate(
    count=models.Count('identifier'),metric_type=models.Value("total-dataset-requests",output_field=models.CharField()),access_method=models.Value("regular",output_field=models.CharField())
)

这给了我<Queryset []>如下:

<QuerySet [{'identifier': '10.80519/954e-4db4','country': 'fr','count': 1,'metric_type': 'total-dataset-requests','access_method': 'regular'},{'identifier': '10.80519/954e-4db4','country': 'gb','count': 5,'access_method': 'regular'}]>

如您所见,我拥有模仿上述数据结构所需的所有数据。但是以一种晦涩难懂的格式...我可以使用Python从values_list()或iterator()中进行清理,但是我想通过ORM对数据库层进行大部分繁重的工作。

所以我想我的问题是, 我如何将JSON结构中所示的聚合对象复制为ORM查询...?

仅供参考:从models.py中了解完整的LogItem

class LogItem(models.Model):
    ....

    id = models.AutoField(_('ID'),primary_key=True)

    session_id = models.TextField(_('Session ID'),default='')

    doubleclick_id = models.TextField(_('Doubleclick ID'),default='')

    event = models.DateTimeField(_('Event Recorded At'),default=Now,blank=True)

    client_ip = models.CharField(_('Client IP'),max_length=15,null=True,blank=True)

    session_cookie_id = models.CharField(_('Session Cookie ID'),max_length=120,blank=True)

    user_cookie_id = models.CharField(_('User Cookie ID'),blank=True)

    user_id = models.CharField(_('User ID'),max_length=100,blank=True)

    request_url = models.TextField(_('Request URL'),default='')

    identifier = models.CharField(_('Identifier'),blank=True)

    filename = models.TextField(_('Filename'),null=True)

    size = models.PositiveBigIntegerField(_('Size'),null=True)

    user_agent = models.TextField(_('User Agent'),default='')

    # Alpha-2 ISO 3166 Codes: [Reference: Country Codes Alpha-2 & Alpha-3](https://www.iban.com/country-codes)
    country = models.CharField(_('Country'),max_length=10,default='gb')

    hit_type = models.CharField(_('Hit Type'),max_length=60,blank=True)

    is_robot = models.BooleanField(_('Is Robot'),default=False)

    is_machine = models.BooleanField(_('Is Machine'),default=False)

解决方法

我认为您只能在python中而不是QuerySet中执行此操作,因为Queryset是数据库“ SELECT”表示形式,据我所知,您不能在查询集中包含字典“ country-counts”,而不是生成结果使用custom model Serializer Method或python代码:

序列化器示例

    class LogItemSerializer(serializers.ModelSerializer):
        country_counts = serializers.SerializerMethodField()

        class Meta:
            model = LogItem

        def get_country_counts(self,obj):
            # create the dic you want
            result = {
                  "au": 6,"jp": 1,"us": 13
                  }
            return result

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...