标签:tar html get length int ann void 我不知道 else
我们来看下面的例子:
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:添加getter来建模并使用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‘)
上面的代码可能被重构了一点,但是它不会改变这个事实,这个选项将对IceCream公司执行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查询中获取聚合字段,但是我不知道如何将它们添加到Serializer中,因为DRF不会神奇地知道我在QuerySet中注释了这些字段.如果我将total_trucks和total_capacity添加到序列化程序中,那么它将抛出一个关于模型中不存在的这些字段的错误.
选项2可以通过使用View而不使用串行器来实现,但是如果模型包含很多字段,并且只有一些需要在JSON中,那么在没有串行器的情况下构建端点将是一个有些丑陋的攻击.
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‘)
)
serializers.py
class IceCreamCompanySerializer(serializers.ModelSerializer):
total_trucks = serializers.IntegerField()
total_capacity = serializers.IntegerField()
class Meta:
model = IceCreamCompany
fields = (‘name‘, ‘total_trucks‘, ‘total_capacity‘)
通过使用Serializer fields我有一个小例子上班.这些字段必须声明为序列化程序的类属性,因此DRF不会在IceCreamCompany模型中抛出不存在的错误.
Django Rest Framework序列化程序中的聚合(和其他注释)字段
标签:tar html get length int ann void 我不知道 else
原文地址:https://www.cnblogs.com/catgatp/p/12880047.html