将Django序列化器包装在另一个序列化器中

时间:2019-10-10 15:53:25

标签: python django django-models django-rest-framework

我需要在Django中使用嵌套的序列化程序。我有以下有效的序列化器:

class LocationSerializer(serializers.ModelSerializer):
    coordinate = serializers.SerializerMethodField()
    message = serializers.SerializerMethodField()

    def get_message(self, instance: models.Location):
        if len(instance.message) > 1:
            return instance.message
        return None

    def get_coordinate(self, instance: models.Location):
        if instance.point:
            return {"latitude": instance.point.y, "longitude": instance.point.x}

    class Meta:
        model = models.Location
        fields = ('id', 'street', 'zip', 'phone', 'coordinate', 'message')

此序列化程序生成的json需要包装在一个json对象中,如下所示:

{
    "locations": //here comes the serialized data
}

我用另一个序列化程序尝试了以下方法,该序列化程序在字段中具有上面的序列化程序:

class LocationResponseSerializer(serializers.Serializer):

    locations = LocationSerializer(many=True)

但是当我尝试使用此序列化程序时,总是会出现以下错误:

 The serializer field might be named incorrectly and not match any attribute or key on the `Location` instance.
 Original exception text was: 'Location' object has no attribute 'locations'.

我在做什么错? 仅将其包装在响应对象中是可行的,但不是解决方案,因为与Django一起使用的swagger框架似乎不支持这种方法。

感谢您的帮助!

编辑:这是我视图的列表方法:

def list(self, request, *args, **kwargs):
    # update_compartments()
    queryset = Location.objects.filter(hidden=False).all()
    serializer = LocationResponseSerializer(queryset, many=True)
    return Response(serializer.data)

1 个答案:

答案 0 :(得分:0)

问题在于此序列化程序从 Location.objects.filter(hidden=False).all()查询集,因此将它们逐一序列化。

class LocationResponseSerializer(serializers.Serializer):
    locations = LocationSerializer(many=True)

如果包装响应对您而言效果不佳,则可以尝试

class LocationResponseSerializer(serializers.Serializer):
    locations = LocationSerializer(source="*")

但这并不是您想要的,因为它将为locations中的每条记录生成queryset

另一个选择是您的看法

def get_queryset(self):
    locations = Location.objects.filter(hidden=False).all()
    return { 'locations': locations }

或将您的列表方法更改为

def list(self, request, *args, **kwargs):
    # update_compartments()
    data = Location.objects.filter(hidden=False).all()
    queryset = { 'locations': data }
    serializer = LocationResponseSerializer(queryset)
    return Response(serializer.data)

但是在这种情况下,您可能还需要编写一个自定义分页器,因为如果需要它将无法立即使用

希望有帮助