django: django rest framework 嵌套序列化

django: django rest framework 嵌套序列化


项目示例代码github地址:https://github.com/jinjidejuren/drf_learn

django rest framework序列化在其他的章节中进行了讲解,如果我们需要进行嵌套序列化,则需要对序列化类进行扩展,需要结合具体的需求进行设计。例如在设备这个模型的序列化类中,我们不仅需要获取服务器的信息,还想要获取设备所在机柜的信息。

class DeviceSerializer(serializers.ModelSerializer):
    """
    设备序列化
    """
    cabinet = serializers.SerializerMethodField()

    def get_cabinet(self, obj):
        cabinets = Cabinet.objects.filter(id=obj.cabinet_id)
        if cabinets is not None and len(cabinets) > 0:
            return CabinetSerializer(cabinets[0]).data
        else:
            return ""

    class Meta:
        model = Device
        fields = ('id', 'device_name', 'device_type', 'brand', 'model',
                  'hardware', 'cabinet_id', 'cabinet', 'created_time', 'modified_time')

对于设备的序列化,我们在fields中添加了cabinet的信息,这个不是Device中原有的字段信息。额外添加需要进行定义。

cabinet = serializers.SerializerMethodField()

一旦定义了cabinet为SerializerMethodField,需要定义cabinet的获取方法。SerializerMethodField默认为我们提供了一个方法的名称method_name

    def bind(self, field_name, parent):
        # In order to enforce a consistent style, we error if a redundant
        # 'method_name' argument has been used. For example:
        # my_field = serializer.SerializerMethodField(method_name='get_my_field')
        default_method_name = 'get_{field_name}'.format(field_name=field_name)
        assert self.method_name != default_method_name, (
            "It is redundant to specify `%s` on SerializerMethodField '%s' in "
            "serializer '%s', because it is the same as the default method name. "
            "Remove the `method_name` argument." %
            (self.method_name, field_name, parent.__class__.__name__)
        )

其中method_name需要满足名称为’get_{field_name}’.format(field_name=field_name),所以cabinet对应的获取方法为get_cabinet:

    def get_cabinet(self, obj):
        cabinets = Cabinet.objects.filter(id=obj.cabinet_id)
        if cabinets is not None and len(cabinets) > 0:
            return CabinetSerializer(cabinets[0]).data
        else:
            return ""

接着访问http://127.0.0.1:8060/assets/v1/devices/,可以得到device的信息以及device对应的cabinet信息:

GET /assets/v1/devices/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "device_name": "test-device1",
            "device_type": "storage",
            "brand": "dell",
            "model": "HPE Apollo 4200 Gen9",
            "hardware": "test-device1 hardware info",
            "cabinet_id": 1,
            "cabinet": {
                "id": 1,
                "cabinet_name": "first-cabinet",
                "cabinet_code": "1",
                "room_id": 1,
                "created_time": "2018-07-10T13:05:46.155102Z",
                "modified_time": null
            },
            "created_time": "2018-07-10T13:04:48.677079Z",
            "modified_time": null
        },
        {
            "id": 2,
            "device_name": "test-device2",
            "device_type": "storage",
            "brand": "dell",
            "model": "HPE Apollo 4200 Gen9",
            "hardware": "test-device2 hardware info",
            "cabinet_id": 2,
            "cabinet": {
                "id": 2,
                "cabinet_name": "second-cabinet",
                "cabinet_code": "2",
                "room_id": 1,
                "created_time": "2018-07-10T13:05:57.101426Z",
                "modified_time": null
            },
            "created_time": "2018-07-10T13:05:01.953900Z",
            "modified_time": null
        },
        {
            "id": 3,
            "device_name": "test-device3",
            "device_type": "safe",
            "brand": "dell",
            "model": "HPE Apollo 4200 Gen9",
            "hardware": "test-device3 hardware info",
            "cabinet_id": 1,
            "cabinet": {
                "id": 1,
                "cabinet_name": "first-cabinet",
                "cabinet_code": "1",
                "room_id": 1,
                "created_time": "2018-07-10T13:05:46.155102Z",
                "modified_time": null
            },
            "created_time": "2018-07-10T13:05:14.653610Z",
            "modified_time": null
        }
    ]
}

cabinet只是说明了嵌套序列化的方法,在实际应用中可以根据需求进行更多的嵌套序列化。

你可能感兴趣的:(python,django,实战)