复杂Django ORM注释和聚合

复杂Django ORM注释和聚合,django,django-queryset,django-orm,django-annotate,django-aggregation,Django,Django Queryset,Django Orm,Django Annotate,Django Aggregation,我目前正在准备将一些日志项转换为JSON序列化格式 我试图通过Django的内置ORM,利用注释和聚合来实现这一点 我正在尝试为每个记录的项目复制以下结构: ... { "count": 20, "metric-type": "total-dataset-requests", "access-method": "regular", "country-cou

我目前正在准备将一些日志项转换为JSON序列化格式

我试图通过Django的内置ORM,利用注释和聚合来实现这一点

我正在尝试为每个记录的项目复制以下结构:

...
{
    "count": 20,
    "metric-type": "total-dataset-requests",
    "access-method": "regular",
    "country-counts": {
        "au": 6,
        "jp": 1,
        "us": 13
    }
}
...
我目前根据自己的知识构建了此查询集:

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 [{'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, 'metric_type': 'total-dataset-requests', 'access_method': 'regular'}]>

我认为您只能在python中而不能在QuerySet中执行此操作,因为QuerySet是一种数据库选择表示,而且据我所知,您不能在QuerySet中包含字典国家/地区计数,而不是在或python代码中生成结果:

序列化程序示例:

类LogItemSerializerserializers.ModelSerializer: 国家/地区计数=serializers.SerializerMethodField 类元: 模型=登录项 def get_国家/地区自身,obj: 创建您想要的dic 结果={ 非盟:6, jp:1,, 美国:13 } 返回结果
您只需将现有的结构映射到代码中所需的结构。@bryan60不幸的是,我需要此格式的日志用于另一个验证步骤。因此,请在该步骤之前映射它?它们一次只记录一个。您在这里并不清楚您需要什么或您的意思。从我在您的问题中看到的情况来看,您已经在数据库层完成了所有繁重的查询,并以稍微不同的格式获得了所需的聚合信息。如果这是真的,这里的解决方案显然是只使用查询集并对其进行修改,而不是试图诱使SQLORM提供非表格数据。如果没有,你应该澄清除了格式之外,你在结果中没有得到什么。获取数据是数据库的范围,格式化数据是为了视图。
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, null=True, blank=True)

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

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

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

    identifier = models.CharField(_('Identifier'), max_length=120, null=True, 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, null=True, blank=True)

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

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