Django : KeyError: "Получена ошибка KeyError при попытке получить значение для поля `channel` на сериализаторе ``...
модель
class Metric(models.Model):
date = models.DateField()
channel = models.CharField(max_length=50)
country = models.CharField(max_length=10)
os = models.CharField(max_length=10)
impressions = models.IntegerField()
clicks = models.IntegerField()
def __str__(self):
return "{} - {}".format(self.date, self.channel)
Мое мнение
class MetricViewSet(viewsets.ModelViewSet):
serializer_class = MetricSerializer
queryset = Metric.objects.all()
filter_backends = [DjangoFilterBackend]
filterset_class = MetricFilter
Мой сериализатор
class MetricSerializer(serializers.ModelSerializer):
class Meta:
model = Metric
fields = '__all__'
Мне нужно сгруппировать по одному или нескольким столбцам: дата, канал, страна, операционная система и сериализовать это. Может ли кто-нибудь помочь мне, как я могу это сделать?
select channel, country, sum(impressions) as impressions, sum(clicks) as clicks from sample dataset where date < '2017-06-01' group by channel, country order by clicks desc;
channel | country | impressions | clicks
------------------+---------+-------------+--------
adcolony | US | 532608 | 13089
apple_search_ads | US | 369993 | 11457
vungle | GB | 266470 | 9430
vungle | US | 266976 | 7937
Мое мнение
lass MetricViewSet(viewsets.ModelViewSet):
serializer_class = MetricSerializer
queryset = Metric.objects.all()
filter_backends = [DjangoFilterBackend]
filterset_class = MetricFilter
def get_queryset(self):
sort_by_dict = {'asc': '', 'desc': '-'}
queryset = Metric.objects.all()
group_by = self.request.query_params.get('group_by', None)
# grouping the queryset
if group_by is not None:
queryset = queryset.values(group_by).annotate(dcount=Count(group_by))#.order_by()
return queryset
Я получаю следующую ошибку
KeyError: "Got KeyError when attempting to get a value for field `channel` on serializer `MetricSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'channel'."
Думаю, это будет работать, (не проверял)
from django.db.models import Sum
queryset.values('channel', 'country').order_by().annotate(impressions = sum('impressions'),clicks = sum('clicks'))
Редактирование ---
О, я пропустил некоторые моменты вашего вопроса, я думаю, вам нужно внести небольшие изменения в представление и сериализатор
в этом случае
if group_by is not None:
queryset = queryset.values(group_by).order_by().annotate(impressions = sum('impressions'),clicks = sum('clicks'))
А ваш сериализатор способен обрабатывать необязательные поля
from rest_framework import serializers
class MetricSerializer(serializers.Serializer):
date = serializers.DateField()
channel = title = serializers.CharField(required=False, max_length=50, allow_blank=True)
country = title = serializers.CharField(required=False, max_length=10, allow_blank=True)
os = title = serializers.CharField(required=False, max_length=10, allow_blank=True)
impressions = serializers.IntegerField()
clicks = serializers.IntegerField()