问题描述
我目前正在将一些记录的项目准备为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