如何序列化相关模型中的字段。
我得到了一个模型:
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?
get_queryset
方法需要返回一个查询集,但由于values_list,您返回一个元组。要么删除它以返回查询集,要么使用更通用的视图,如APIView
。
我找到了一个方法。
当我使用。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)