【问题标题】:How to serialize a custom data set of two models in Django Rest Framework如何在 Django Rest Framework 中序列化两个模型的自定义数据集
【发布时间】:2019-07-29 13:43:35
【问题描述】:

我有一个非常重要的查询:我想序列化一组数据,或者更确切地说是一个具有另一个模型的外键的模型,以便通过外键显示另一个表的字段,比如名称:

模型 Equipos


    id_equipo=models.PositiveSmallIntegerField(primary_key=True)
    nombre=models.CharField(max_length=15)
    vendedor=models.CharField(max_length=10,default='S/A',blank=True)
    ip_gestion=models.GenericIPAddressField(protocol='Ipv4',default='0.0.0.0')
    tipo=models.CharField(max_length=8,default='S/A',blank=True)
    localidad=models.CharField(max_length=5,default='S/A',blank=True)
    categoria=models.CharField(max_length=10,default='S/A',blank=True)
    ultima_actualizacion=models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'Equipos'

模型接口

class Interfaces(models.Model):

    id_interface=models.PositiveIntegerField(primary_key=True)
    id_EquipoOrigen=models.ForeignKey(Equipos,on_delete=models.DO_NOTHING,related_name='equipo_origen')

id_PuertoOrigen=models.ForeignKey(Puertos,on_delete=models.DO_NOTHING,related_name='puerto_origen',null=True,blank=True)
    estatus=models.BooleanField(default=False)
    etiqueta_prtg=models.CharField(max_length=80,null=True,blank=True)
    grupo=models.PositiveSmallIntegerField(default=0,blank=True)
    if_index=models.PositiveIntegerField(default=0,blank=True)
    bw=models.PositiveSmallIntegerField(default=0,blank=True)
    bw_al=models.PositiveSmallIntegerField(default=0,blank=True)
    id_prtg=models.PositiveSmallIntegerField(default=0,blank=True)
    ospf=models.BooleanField(default=False)
    description=models.CharField(max_length=200,null=True,blank=True)
    id_EquipoDestino=models.ForeignKey(Equipos,on_delete=models.DO_NOTHING,related_name='equipo_destino')
    id_PuertoDestino=models.ForeignKey(Puertos,on_delete=models.DO_NOTHING,related_name='puerto_destino')
    ultima_actualizacion=models.DateTimeField(auto_now=True)

所以我想创建一个序列化程序,通过接口模型的 Id_EquipoOrigen(指的是 Equipos 模型),它能够在 json 中呈现 Equipos 模型的字段 nombre、localidad、categoria .

我已经有了序列化设备和接口模型


class EquipoSerializer(serializers.ModelSerializer):

    class Meta:
        model=Equipos
        fields=('id_equipo','nombre','vendedor','ip_gestion','tipo','localidad','categoria','ultima_actualizacion')

# Serializando los Datos del Modelo Equipo_Interface(Registros)
class InterfaceSerializer(serializers.ModelSerializer):

    class Meta:
        model=Interfaces
        fields=('id_interface','id_EquipoOrigen','id_PuertoOrigen','estatus','etiqueta_prtg','grupo','if_index','bw','bw_al','id_prtg','ospf','description','id_EquipoDestino','id_PuertoDestino','ultima_actualizacion') 

class EquiposViewSet(viewsets.ModelViewSet):

    queryset=Equipos.objects.all()
    serializer_class=EquipoSerializer

class InterfacesViewSet(viewsets.ModelViewSet):

    queryset=Interfaces.objects.all()
    serializer_class=InterfaceSerializer
    pagination_class=PostPageNumberPagination

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    您可以通过嵌套EquipoSerializer 来实现这一点(或创建一个仅包含您想要显示的字段的较短版本),如下所示:

    class EquipoSerializer(serializers.ModelSerializer):
    
        class Meta:
            model=Equipos
            fields=('id_equipo','nombre','vendedor','ip_gestion','tipo','localidad','categoria','ultima_actualizacion')
    
    class InterfaceSerializer(serializers.ModelSerializer):
    
        id_EquipoOrigen = EquipoSerializer()
    
        class Meta:
            model=Interfaces
            fields=('id_interface','id_EquipoOrigen','id_PuertoOrigen','estatus','etiqueta_prtg','grupo','if_index','bw','bw_al','id_prtg','ospf','description','id_EquipoDestino','id_PuertoDestino','ultima_actualizacion')
    

    对于较短的版本,您可以这样做:

    class NestedEquipoSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Equpos
            fields = ('id_equipo', 'nombre', 'localidad', 'categoria',)
    

    另一种方法是直接在InterfaceSerializer中获取字段:

    class InterfaceSerializer(serializers.ModelSerializer):
    
            nombre_equipo = serializers.CharField(source='id_EquipoOrigen.nombre')
            categoria_equipo = serializers.CharField(source='id_EquipoOrigen.categoria')
            localidad_equipo = serializers.CharField(source='id_EquipoOrigen.localidad')
    
            class Meta:
                model=Interfaces
                fields=('id_interface','id_EquipoOrigen','id_PuertoOrigen','estatus','etiqueta_prtg','grupo','if_index','bw','bw_al','id_prtg','ospf','description','id_EquipoDestino','id_PuertoDestino','ultima_actualizacion', 
                        'nombre_equipo', 'categoria_equipo', 'localidad_equipo')
    

    【讨论】:

    • 如果我想在界面模型中显示,我会这样做,根据具有字段 id_EquipoDestino 的 id 值,显示该团队的名称、类别和 localidad,这已经是在 Equipo 模型中。
    • 我不确定我是否理解您的问题 - 通过嵌套,您将在 Interface 序列化对象中拥有您想要的确切序列化对象。如果您不想直接序列化嵌套对象,您可以像这样在InterfaceSerializer 上声明新字段:nombre_equipo = serializers.CharField(source='id_EquipoOrigen.nombre'),通过指定source,然后您需要将nombre_equipo 添加到您的@ 987654331@.
    • 正是我需要的,直接字段,非常感谢帮助的朋友
    • 然后我将编辑答案并提供更详细的解释,干杯! :)
    • TypeError: 'Teams' object does not support item assignment 我在尝试发帖(创建)时遇到此错误,因为它告诉我必须放置名称、位置、类别等字段Equipo 模型,因为我只想用 id 创建/编辑..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2016-12-03
    • 1970-01-01
    • 2017-06-22
    • 2013-08-03
    相关资源
    最近更新 更多