django 不包括字段 序列化器_Django Rest Framework序列化程序中的聚合(和其他带注释的)字段...

我正在尝试找出将带注释的字段(例如任何聚合的(计算的)字段)添加到DRF(模型)序列化器的最佳方法。我的用例仅是端点返回未存储在数据库中但从数据库计算出的字段的情况。

让我们看下面的例子:

models.py

class IceCreamCompany(models.Model):

name = models.CharField(primary_key = True, max_length = 255)

class IceCreamTruck(models.Model):

company = models.ForeignKey('IceCreamCompany', related_name='trucks')

capacity = models.IntegerField()

serializers.py

class IceCreamCompanySerializer(serializers.ModelSerializer):

class Meta:

model = IceCreamCompany

所需的JSON输出:

[

{

"name": "Pete's Ice Cream",

"total_trucks": 20,

"total_capacity": 4000

},

...

]

我有几个可行的解决方案,但是每个解决方案都有一些问题。

选项1:为模型添加吸气剂并使用SerializerMethodFields

models.py

class IceCreamCompany(models.Model):

name = models.CharField(primary_key=True, max_length=255)

def get_total_trucks(self):

return self.trucks.count()

def get_total_capacity(self):

return self.trucks.aggregate(Sum('capacity'))['capacity__sum']

serializers.py

class IceCreamCompanySerializer(serializers.ModelSerializer):

def get_total_trucks(self, obj):

return obj.get_total_trucks

def get_total_capacity(self, obj):

return obj.get_total_capacity

total_trucks = SerializerMethodField()

total_capacity = SerializerMethodField()

class Meta:

model = IceCreamCompany

fields = ('name', 'total_trucks', 'total_capacity')

上面的代码也许可以重构一点,但是它不会改变以下事实:该选项将对每个IceCreamCompany执行2个额外的SQL查询,这不是很有效。

选项2:在ViewSet.get_queryset中进行注释

最初描述的models.py。

views.py

class IceCreamCompanyViewSet(viewsets.ModelViewSet):

queryset = IceCreamCompany.objects.all()

serializer_class = IceCreamCompanySerializer

def get_queryset(self):

return IceCreamCompany.objects.annotate(

total_trucks = Count('trucks'),

total_capacity = Sum('trucks__capacity')

)

这将在单个SQL查询中获得聚合的字段,但是我不确定如何将它们添加到序列化程序中,因为DRF不可思议地知道我已经在QuerySet中注释了这些字段。如果将total_trucks和total_capacity添加到序列化程序中,它将引发有关模型中不存在这些字段的错误。

通过使用View可以使选项2在不使用序列化器的情况下工作,但是如果模型包含很多字段,并且JSON中仅要求包含某些字段,那么在没有序列化器的情况下构建端点将是一个有点丑陋的技巧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值