首页 > 解决方案 > 无法序列化 foreignKey 对象数据

问题描述

我有一对多关系 Developer 和 Constructions 我想在序列化 Construction 对象时序列化所有 Developer 字段

请求

{
    "developer": 1,
    "name": "as2",
    "address": "ZZZZZZZZZZZZZsdf",
    "deadline": "2020-05-13 14:26:58",
    "coordinates": { "latitude": 49.8782482189424, "longitude": 24.452545489 }
    
}

我有一个错误:

{
    "developer_data": [
        "This field is required."
    ]
}

这对我来说很奇怪,因为 developer_data 标记为read_only

如何修复错误?我认为这个问题与序列化程序有关

模型.py

class Developer(models.Model):
    name = models.CharField(max_length=100)
    ...

def name_image(instance, filename):
    return '/'.join(['images', str(instance.name), filename])

class Construction(models.Model):
    developer = models.ForeignKey(
        Developer, related_name="constructions", on_delete=models.CASCADE
    )
    name = models.CharField(max_length=100)
    image = models.ImageField(upload_to=name_image, blank=True, null=True)
    ...

serializers.py(更新)

class DeveloperSerializer(serializers.ModelSerializer):
    constructions_number = serializers.SerializerMethodField()
    workers_number = serializers.SerializerMethodField()
    machines_number = serializers.SerializerMethodField()

    class Meta:
        model = Developer
        fields = ('id', 'name', 'constructions_number', 'workers_number', 'machines_number')
    
    def create(self, validated_data):
        instance = super().create(validated_data=validated_data)
        return instance
    
    def get_constructions_number(self, obj):
        return obj.constructions.count()
    
    def get_workers_number(self, obj):
        res = obj.constructions.aggregate(Sum('workers_number'))['workers_number__sum']
        if res:
            return res
        return 0

    def get_machines_number(self, obj):
        res = obj.constructions.aggregate(Sum('machines_number'))[ "machines_number__sum"]
        if res:
            return res
        return 0
    


class ConstructionSerializer(serializers.ModelSerializer):
    coordinates = PointField()
    deadline = serializers.DateTimeField(format=TIME_FORMAT)
    cameras_number = serializers.SerializerMethodField()
    developer = DeveloperSerializer()

    class Meta:
        model = Construction
        fields = (
            'id', 'developer', 'name', 'image', 'address', 'coordinates', 'deadline',
            'workers_number', 'machines_number', 'cameras_number',
        )
        read_only_fields = ('workers_number', 'machines_number', 'cameras_number')
    
    def create(self, validated_data):
        instance = super().create(validated_data=validated_data)
        return instance
    
    def get_cameras_number(self, obj):
        return obj.cameras.count()

我对views.py中的模型使用标准ModelViewSet,我认为serializers.py中的问题

标签: pythondjangodjango-rest-framework

解决方案


您正在使用开发人员序列化程序错误,将其更改ConstructionSerializer

class ConstructionSerializer(serializers.ModelSerializer):
    coordinates = PointField()
    deadline = serializers.DateTimeField(format=TIME_FORMAT)
    cameras_number = serializers.SerializerMethodField()
    developer = DeveloperSerializer()

    class Meta:
        model = Construction
        fields = (
            'id', 'developer', 'name', 'image', 'address', 'coordinates', 'deadline',
            'workers_number', 'machines_number', 'cameras_number',
        )
        read_only_fields = ('workers_number', 'machines_number', 'cameras_number', 'developer') # if you don't want developer to be read only then remove it from there
    
    def create(self, validated_data):
        instance = super().create(validated_data=validated_data)
        return instance
    
    def get_cameras_number(self, obj):
        return obj.cameras.count()

推荐阅读