Python 如何使用DRF序列化django中的一些嵌套关系模型?

Python 如何使用DRF序列化django中的一些嵌套关系模型?,python,django,django-models,django-rest-framework,django-serializer,Python,Django,Django Models,Django Rest Framework,Django Serializer,我有一些彼此关系不同的django模型(即多对多,Foreignkey)。现在,我想使用djnagorest对它们进行序列化 以下是我的模型及其关系的示例: class CommonFieldsAbstarct(models.Model): name=models.CharField(最大长度=30,唯一性=True) 类服务器模型(CommonFieldsBStarct): server_ip=models.genericpaddressfield(默认值为172.17.0.1') 服务器\u

我有一些彼此关系不同的django模型(即多对多,Foreignkey)。现在,我想使用
djnagorest
对它们进行序列化

以下是我的模型及其关系的示例:

class CommonFieldsAbstarct(models.Model):
name=models.CharField(最大长度=30,唯一性=True)
类服务器模型(CommonFieldsBStarct):
server_ip=models.genericpaddressfield(默认值为172.17.0.1')
服务器\u端口=models.IntegerField(默认值='9001')
类SNMPLineModel(CommonFieldsBStarct):
ip_地址=models.GenericIPAddressField()
端口=models.IntegerField(默认值=161)
类别SNMPModel(CommonFieldsBStarct):#目标
line=models.ForeignKey(SNMPLineModel,on_delete=CASCADE)
servers=models.ManyToManyField(ServerModel)
类MetaDataModel(models.Model):
key=models.CharField(最大长度=20)
值=models.CharField(最大长度=20)
snmp\u device=models.ForeignKey(SNMPModel,on\u delete=CASCADE)
以前,我使用这种方式手动创建json:

def meta_data_json(meta_data):
元数据列表=[]
对于元数据中的元数据:
元数据列表.append({
meta.key:meta.value
})
返回元数据列表
def server_json(服务器):
返回[{'ip':server.server\u ip,
“端口”:server.server\u port}
用于服务器中的服务器]
def create_json():
snmp=SNMPModel.objects.filter(name\uu包含class='a-name')
返回{
“名称”:snmp.name,
“地址”:snmp.line.ip_地址,
“端口”:snmp.line.port,
“服务器”:服务器\u json(snmp.servers.all()),
“meta_data”:meta_data_json(MetaDataModel.objects.filter(
snmp\u设备=snmp.pk
)
),
'device_pk':snmp.pk
}

我的问题: 现在,我如何通过
django rest框架
创建这样一个json呢

我对多对多没有任何问题。事实上,我的问题在于他们的
外键

以下是我到目前为止所做的:

序列化程序.py

从rest\u框架导入序列化程序
类MetaDataSerializer(serializers.ModelSerializer):
类元:
字段=[
“id”,
“钥匙”,
“价值”,
]
模型=元数据模型
类ServerSerializer(serializers.ModelSerializer):
类元:
字段=[
“id”,
“服务器ip”,
“服务器端口”,
]
model=ServerModel
类LineSerializer(serializers.ModelSerializer):
port=serializers.RelatedField(many=True)
类元:
字段='\uuuu所有\uuuu'
model=SNMPLineModel
类SNMPSerializer(serializers.ModelSerializer):
servers=ServerSerializer(many=True,read_only=True)#正常
meta_data=MetaDataSerializer(many=True,read_only=True)#这不好
line=LineSerializer(many=True,read_only=True)#不正常
address=serializers.CharField(source=SNMPLineModel.ip#u address)#不正常
port=serializers.CharField(source=SNMPLineModel.port)#不正常
类元:
字段=[
“id”,
“服务器”,
“姓名”,
"地址",,
“港口”,
"行",,
“元数据”
]
model=SNMPModel
views.py

从django.views.decorators.csrf导入csrf\u豁免
从django.http导入HttpResponse,JsonResponse
@豁免
def代码段详细信息(请求、名称):
尝试:
snmp\u conf=SNMPModel.objects.filter(name\u contains=name)
除SNMPModel.DoesNotExist外:
返回HttpResponse(状态=404)
如果request.method==“GET”:
serializer=SNMPSerializer(snmp_conf,many=True)
返回JsonResponse(serializer.data,status=200,safe=False)
url.py

从django.url导入路径
URL模式=[
路径('snippets/',views.snippet_detail)
]

任何帮助都将不胜感激。

序列化程序。SerializerMethodField()
是添加此类关系的有用方法。
get\u meta\u data()

地址和端口似乎是一个简单的关系,
line.FOO
应该可以工作

class SNMPSerializer(serializers.ModelSerializer):
    servers = ServerSerializer(many=True, read_only=True)  # It is ok
    meta_data = serializers.SerializerMethodField()
    line = serializers.SerializerMethodField()
    address = serializers.CharField(source="line.ip_address", read_only=True)
    port = serializers.CharField(source="line.port" , read_only=True)

    class Meta:
        fields = ['id', 'servers', 'name', 'address', 'port', 'line', 'meta_data']
        model = SNMPModel

    def get_meta_data(self, instance):
        metadatamodels = MetaDataModel.objects.filter(snmp_device=instance)
        serializer = MetaDataSerializer(instance=metadatamodels, many=True, read_only=True)

        return serializer.data

    def get_line(self, instance):
        serializer = LineSerializer(instance.line, read_only=True)

        return serializer.data

感谢您的回复,我正在尝试使用您的代码片段。但是我对
“line.port”
有点确信,你的意思是
“SNMPLineModel.port”
?我想如果喜欢
instance.line.port
,但DRF不需要我们指定
instance
。我如何解决这个错误:
类型错误:'SNMPLineModel'对象不适合
是由
get\u line()中的这一行引起的
方法:
返回serializer.data
ahh,这应该是一个queryset
instance=instance.line
?我通过删除
many=True
解决了这个问题,我的意思是:
serializer=LineSerializer(instance.line,read\u only=True)