gpt4 book ai didi

django - Django REST Framework 序列化程序中的嵌套注释字段

转载 作者:行者123 更新时间:2023-12-01 11:46:58 28 4
gpt4 key购买 nike

我正在尝试查看 Django REST Framework 序列化程序中的嵌套注释(聚合/计算)字段。这将允许更干净地使用带注释的字段。这个帖子类似于Aggregate (and other annotated) fields in Django Rest Framework serializers但是我想要一个类似的技术来嵌套工作。下面的方法是可见的,它是如何在没有嵌套的情况下工作的,以及它似乎如何不与嵌套一起工作。

我知道这可以手动(使用 Django View )或使用重载我不感兴趣的数据库的方法来实现。但也许这个问题有一个高性能和优雅的解决方案。

以下作品(非嵌套)

楷模

class IceCreamCompany(models.Model):
name = models.CharField(max_length=255)


class IceCreamTruck(models.Model):
company = models.ForeignKey('IceCreamCompany', related_name='trucks')
capacity = models.IntegerField()


class IceCreamTruckDriver(models.Model):
name = models.CharField(max_length=255)
first_name = models.CharField(max_length=255)
truck = models.ForeignKey('IceCreamTruck', related_name='drivers')

序列化器
class IceCreamTruckDriverSerializer(serializers.ModelSerializer):

class Meta:
model = IceCreamTruckDriver
fields = ('name', 'first_name')


class IceCreamTruckSerializer(serializers.ModelSerializer):
drivers = IceCreamTruckDriverSerializer(many=True, read_only=True)

class Meta:
model = IceCreamTruck
fields = ('capacity', 'drivers')


class IceCreamCompanySerializer(serializers.ModelSerializer):
trucks = IceCreamTruckSerializer(many=True, read_only=True)
amount_of_trucks = serializers.IntegerField()

class Meta:
model = IceCreamCompany
fields = ('name', 'trucks', 'amount_of_trucks')

View 集
class IceCreamCompanyViewSet(viewsets.ModelViewSet):
queryset = IceCreamCompany.objects.prefetch_related('trucks', 'trucks__drivers')\
.annotate(amount_of_trucks=Count('trucks'))\
.all()

serializer_class = IceCreamCompanySerializer

结果
"results": [
{
"name": "Pete Ice Cream",
"trucks": [
{
"capacity": 35,
"drivers": [
{
"name": "Damian",
"first_name": "Ashley"
},
{
"name": "Wilfrid",
"first_name": "Lesley"
}
]
},
{
"capacity": 30,
"drivers": [
{
"name": "Stevens",
"first_name": "Joseph"
}
]
},
{
"capacity": 30,
"drivers": []
}
],
"amount_of_trucks": 3
}
]

以下不起作用(嵌套)

相同型号

序列化器
class IceCreamTruckDriverSerializer(serializers.ModelSerializer):

class Meta:
model = IceCreamTruckDriver
fields = ('name', 'first_name')


class IceCreamTruckSerializer(serializers.ModelSerializer):
drivers = IceCreamTruckDriverSerializer(many=True, read_only=True)
amount_of_drivers = serializers.IntegerField()

class Meta:
model = IceCreamTruck
fields = ('capacity', 'drivers', 'amount_of_drivers')


class IceCreamCompanySerializer(serializers.ModelSerializer):
trucks = IceCreamTruckSerializer(many=True, read_only=True)

class Meta:
model = IceCreamCompany
fields = ('name', 'trucks')

View 集
class IceCreamCompanyViewSet(viewsets.ModelViewSet):
queryset = IceCreamCompany.objects.prefetch_related('trucks', 'trucks__drivers')\
.annotate(trucks__amount_of_drivers=Count('trucks__drivers'))\
.all()

serializer_class = IceCreamCompanySerializer

结果
AttributeError at /ice/
Got AttributeError when attempting to get a value for field `amount_of_drivers` on serializer `IceCreamTruckSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `IceCreamTruck` instance.
Original exception text was: 'IceCreamTruck' object has no attribute 'amount_of_drivers'.

最佳答案

作为引用,还可以在模型 IceCreamTruck 上注释每辆卡车的司机数量,例如使用自定义管理器:

class AnnotatedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(amount_of_drivers=Count('drivers'))

class IceCreamTruck(models.Model):
company = models.ForeignKey('IceCreamCompany', related_name='trucks')
capacity = models.IntegerField()

objects = AnnotatedManager()

那么你不需要注释 View 集,因为 amount_of_drivers已在 trucks 上注释:
class IceCreamCompanyViewSet(viewsets.ModelViewSet):
queryset = IceCreamCompany.objects.prefetch_related('trucks', 'trucks__drivers').all()
serializer_class = IceCreamCompanySerializer

它应该比在序列化器内计数更有效。

关于django - Django REST Framework 序列化程序中的嵌套注释字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32964820/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com