Skip to main content
 首页 » 编程设计

python之如何在 Django REST Framework 中序列化继承模型

2024年09月07日25三少

我正在开发一个 Django Rest Framework 项目,我在其中创建了以下模型:

from django.db import models 
 
# Base Models... 
choices = ( 
    ('Single', 'Single'), 
    ('Multiple', 'Multiple'), 
) 
 
 
class UserAccountModel(models.Model): 
    deployment_name = models.CharField(max_length=150, blank=True) 
    credentials = models.FileField(upload_to='media/credentials/', name='credentials'), 
    project_name = models.CharField(max_length=150, blank=True) 
    project_id = models.CharField(max_length=100, blank=False, name='project_id') 
    cluster_name = models.CharField(max_length=150, blank=False) 
    zone_region = models.CharField(max_length=150, blank=False) 
    services = models.CharField(max_length=100, choices=choices) 
 
    def __str__(self): 
        return self.deployment_name 
 
 
class AwdModel(UserAccountModel): 
    source_zip = models.FileField(upload_to='media/awdSource/', name='awd_source') 
    routing = models.TextField(name='routing', null=True) 
 
    def __str__(self): 
        return self.deployment_name 
 
    def save(self, **kwargs): 
        if not self.id and self.services == 'Multiple' and not self.routing: 
            raise ValidationError("You must have to provide routing for multiple services deployment.") 
        super().save(**kwargs) 
 
    # def clean(self): 
    #     if self.services == 'Multiple' and self.routing is None: 
    #         raise ValidationError('You must have to provide routing for multiple services deployment.') 
 
 
class AwodModel(UserAccountModel): 
    source_zip = models.FileField(upload_to='media/awodSource/', name='awod_source') 
    routing = models.TextField({'type': 'textarea'}, name='routing') 
 
    def save(self, **kwargs): 
        if not self.id and self.services == 'Multiple' and not self.routing: 
            raise ValidationError("You must have to provide routing for multiple services deployment.") 
        super().save(**kwargs) 

我需要序列化这些模型,下面是我如何为这些模型实现序列化程序:

from rest_framework import serializers 
from .models import UserAccountModel, AwdModel, AwodModel 
 
 
class UserAccountSerializer(serializers.ModelSerializer): 
    class Meta: 
        model = UserAccountModel 
        fields = ('deployment_name', 'credentials', 'project_name', 
                  'project_id', 'cluster_name', 'zone_region', 'services') 
 
 
class AWDSerializer(serializers.ModelSerializer): 
    class Meta(UserAccountSerializer.Meta): 
        model = AwdModel 
        fields = UserAccountSerializer.Meta.fields + ('awd_source', 'routing',) 
 
 
class AWODSerializer(serializers.ModelSerializer): 
    class Meta: 
        model = AwodModel 
        fields = '__all__' 

但是,当我尝试访问 AWDSerialzer 时,它返回一个错误:

AttributeError at /api/v1/deployments/ Got AttributeError when attempting to get a value for field project_id on serializer AWDSerializer. The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance. Original exception text was: 'QuerySet' object has no attribute 'project_id'.

更新:这是我的 APIView 代码:

class DeploymentsList(APIView): 
    def get(self, request): 
        MAX_OBJECTS = int(20) 
        deployments = AwdModel.objects.all()[:MAX_OBJECTS] 
        data = AWDSerializer(deployments).data 
        return Response(data) 
 
 
class DeploymentDetail(APIView): 
    def get(self, request, *args, **kwargs): 
        deployment = get_object_or_404(AwdModel, pk=kwargs['pk']) 
        data = AWDSerializer(deployment).data 
        return Response(data) 

请帮帮我!

提前致谢!

请您参考如下方法:

AttributeError at /api/v1/deployments/ Got AttributeError when attempting to get a value for field project_id on serializer AWDSerializer. The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance. Original exception text was: 'QuerySet' object has no attribute 'project_id'.

这是一个属性错误,当试图从字段 project_id 获取值时。

去掉 project_id 字段中的 name 属性。

编辑 APIView 代码

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized. [Serializing multiple objects]

class DeploymentsList(APIView): 
    def get(self, request): 
        MAX_OBJECTS = int(20) 
        deployments = AwdModel.objects.all()[:MAX_OBJECTS] 
        data = AWDSerializer(deployments, many=True).data 
        return Response(data) 

希望对您有所帮助。