如何序列化相关模型中的字段。
我有一个模特:
class Order(models.Model):
order_id = models.BigIntegerField(verbose_name='Order ID', unique=True)
order_name = models.CharField(verbose_name='Order name', max_length=255)
order_type = models.IntegerField(verbose_name='Campaign type')
class Types(models.Model):
delimiter = models.CharField(verbose_name='Delimiter', max_length=255)
status = models.BooleanField(verbose_name='Status', default=True)
title = models.CharField(verbose_name='Title', max_length=255)
class User(models.Model):
name = models.CharField(verbose_name='User name', max_length=200, unique=True)
class Report(models.Model):
order = models.ForeignKey(Order, to_field='order_id', verbose_name='Order ID')
user = models.ForeignKey(User, verbose_name='User ID')
ad_type = models.ForeignKey(Types, verbose_name='Type')
imp = models.IntegerField(verbose_name='Total imp')
month = models.DateField(verbose_name='Month', default=datetime.datetime.today)
查看:
class ReportLisAPIView(ListAPIView):
serializer_class = ReportSerializer
def get_queryset(self):
month = parse_date(self.kwargs['month']) - relativedelta(day=1)
queryset = (
Report.objects.filter(month=month)
.values_list(
'user', 'user__name', 'order__order_id',
'order__order_name', 'order__order_type'
).all().annotate(Sum('imp'))
)
return queryset
串行:
class ReportSerializer(ModelSerializer):
class Meta:
model = Report
depth = 1
我需要在get_queryset()中的'queryset'中获取所有字段 但是我收到了一个错误:
尝试获取字段imp
的值时,获得了AttributeError 序列化器
ReportSerializer
。序列化程序字段可能已命名 错误且不匹配tuple
上的任何属性或键 实例。原始异常文本是:'tuple'对象没有属性 '小鬼'。
但是如果我在get_queryset()中返回只是Report.objects.filter(month = month).all()我将获得所有对象和相关对象的所有字段,没有imp的聚合而不是分组。
所以问题是如何在queryset中设置序列化器返回结构?
答案 0 :(得分:1)
get_queryset
方法需要返回一个查询集,但由于values_list而返回一个元组。删除它以返回查询集或使用更通用的视图,如APIView
。
答案 1 :(得分:0)
我找到了一种方法。
当我使用.values_list()时,它返回列表对象而不是queryset对象。因此,对于序列化程序,请了解列表中的内容,我在序列化程序中定义了所有字段。在to_representation()中,我返回字典应该是。
串行:
class ReportSerializer(serializers.ModelSerializer):
user = serializers.IntegerField()
user_name = serializers.CharField()
order_id = serializers.IntegerField()
order_name = serializers.CharField()
order_type = serializers.IntegerField()
imp = serializers.IntegerField()
class Meta:
model = Report
fields = [
'user', 'user_name', 'order_id', 'order_name',
'order_type', 'imp'
]
depth = 1
def to_representation(self, instance):
Reports = namedtuple('Reports', [
'user',
'user_name',
'order_id',
'order_name',
'order_type',
'imp',
])
return super(ReportSerializer, self).to_representation(
Reports(*instance)._asdict()
)
查看:
class ReportLisAPIView(ListAPIView):
serializer_class = ReportSerializer
def get_queryset(self):
month = parse_date(self.kwargs['month']) - relativedelta(day=1)
queryset = (
Report.objects.filter(month=month)
.values_list(
'user', 'user__name', 'order__order_id',
'order__order_name', 'order__order_type'
).all().annotate(Sum('imp'))
)
return queryset
def list(self, *args, **kwargs):
queryset = self.get_queryset()
serializer = self.serializer_class(queryset, many=True)
# actualy that's it! part of which is below can be pass and just
# return Response(serializer.data)
result = {
'month': parse_date(self.kwargs['month']).strftime('%Y-%m'),
'reports': []
}
inflcr = {}
for item in serializer.data:
inflcr.setdefault(item['user'], {
'id': item['user'],
'name': item['user_name'],
'campaigns': []
})
orders = {
'id': item['order_id'],
'name': item['order_name'],
'type': item['order_type'],
'impressions': item['imp'],
}
inflcr[item['user']]['campaigns'].append(orders)
result['reports'] = inflcr.values()
return Response(result)