You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Django+React开发时,如何显示关联表名称而非ID?

解决Django+React关联表显示ID而非名称的问题

方案1:快速实现只显示名称(适合仅需名称的场景)

步骤1:修改Django Serializer

将Serializer中的PrimaryKeyRelatedField替换为SerializerMethodField,直接返回关联表的名称字段:

class ProductoSerializer(serializers.ModelSerializer):
    # 自定义每个关联字段的返回值
    categoria = serializers.SerializerMethodField()
    marca = serializers.SerializerMethodField()
    modelo = serializers.SerializerMethodField()
    calidad = serializers.SerializerMethodField()
    proveedor = serializers.SerializerMethodField()

    # 分别实现每个字段的取值方法
    def get_categoria(self, obj):
        return obj.categoria.nombre
    def get_marca(self, obj):
        return obj.marca.nombre
    def get_modelo(self, obj):
        return obj.modelo.nombre
    def get_calidad(self, obj):
        return obj.calidad.nombre
    def get_proveedor(self, obj):
        return obj.proveedor.nombre

    class Meta:
        model = Producto
        fields = [
            'id',
            'nombre',
            'precio',
            'stock',
            'categoria',
            'marca',
            'modelo',
            'calidad',
            'proveedor'
        ]

这个方法的优势:

  • 无需修改React代码,ProductoCard.jsx中{producto.categoria}直接显示名称
  • 创建/更新时依然可以传ID,Serializer会自动处理模型外键关联

补充:如果关联模型的__str__已返回名称

如果你的Categoria、Marca等模型已经定义了__str__方法返回nombre(比如def __str__(self): return self.nombre),可以更简单地用StringRelatedField替换:

class ProductoSerializer(serializers.ModelSerializer):
    categoria = serializers.StringRelatedField()
    marca = serializers.StringRelatedField()
    modelo = serializers.StringRelatedField()
    calidad = serializers.StringRelatedField()
    proveedor = serializers.StringRelatedField()

    class Meta:
        model = Producto
        fields = [
            'id',
            'nombre',
            'precio',
            'stock',
            'categoria',
            'marca',
            'modelo',
            'calidad',
            'proveedor'
        ]

注意:StringRelatedField是只读字段,创建/更新时依然需要传ID,Serializer会自动映射到外键字段。


方案2:返回完整关联对象(适合需要更多关联字段的场景)

如果后续需要用到关联表的其他字段(比如Categoria的描述),可以用嵌套序列化:

步骤1:创建关联模型的Serializer

# 新增CategoriaSerializer
class CategoriaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Categoria
        fields = ['id', 'nombre']

# 同理创建其他关联模型的Serializer
class MarcaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Marca
        fields = ['id', 'nombre']

class ModeloSerializer(serializers.ModelSerializer):
    class Meta:
        model = Modelo
        fields = ['id', 'nombre']

class CalidadSerializer(serializers.ModelSerializer):
    class Meta:
        model = Calidad
        fields = ['id', 'nombre']

class ProveedorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Proveedor
        fields = ['id', 'nombre']

步骤2:修改ProductoSerializer

使用嵌套序列化返回完整对象,同时添加write_only的ID字段用于创建/更新:

class ProductoSerializer(serializers.ModelSerializer):
    # 只读的嵌套字段,返回完整关联对象
    categoria = CategoriaSerializer(read_only=True)
    marca = MarcaSerializer(read_only=True)
    modelo = ModeloSerializer(read_only=True)
    calidad = CalidadSerializer(read_only=True)
    proveedor = ProveedorSerializer(read_only=True)

    # 只用于写入的ID字段,映射到对应的外键
    categoria_id = serializers.PrimaryKeyRelatedField(queryset=Categoria.objects.all(), source='categoria', write_only=True)
    marca_id = serializers.PrimaryKeyRelatedField(queryset=Marca.objects.all(), source='marca', write_only=True)
    modelo_id = serializers.PrimaryKeyRelatedField(queryset=Modelo.objects.all(), source='modelo', write_only=True)
    calidad_id = serializers.PrimaryKeyRelatedField(queryset=Calidad.objects.all(), source='calidad', write_only=True)
    proveedor_id = serializers.PrimaryKeyRelatedField(queryset=Proveedor.objects.all(), source='proveedor', write_only=True)

    class Meta:
        model = Producto
        fields = [
            'id',
            'nombre',
            'precio',
            'stock',
            'categoria',
            'marca',
            'modelo',
            'calidad',
            'proveedor',
            'categoria_id',
            'marca_id',
            'modelo_id',
            'calidad_id',
            'proveedor_id'
        ]

步骤3:修改React代码

1. 更新ProductoFormPage.jsx的状态和表单字段

将状态中的关联字段改为xxx_id,对应Serializer的写入字段:

const [productos, setProductos] = useState({
    nombre: "",
    precio: "",
    stock: "",
    categoria_id: "",
    marca_id: "",
    modelo_id: "",
    calidad_id: "",
    proveedor_id: "",
});

然后修改每个select的value和onChange:

// 示例:Categoria下拉框
<select
    value={productos.categoria_id}
    onChange={(e) => 
        setProductos({ ...productos, categoria_id: e.target.value })}
>    
    <option value="">---------Categoría---------</option>
    {categorias.map(categoria => (
        <option key={categoria.id} value={categoria.id}>
            {categoria.nombre}    
        </option>  
    ))}
</select>

其他下拉框(Marca、Modelo等)同理修改为marca_id、modelo_id等。

2. 更新ProductoCard.jsx显示名称

现在返回的是完整对象,需要访问nombre属性:

<h3>Categoria: {producto.categoria.nombre}</h3>
<h3>Marca: {producto.marca.nombre}</h3>
<h3>Modelo: {producto.modelo.nombre}</h3>
<h3>Calidad: {producto.calidad.nombre}</h3>
<h3>Proveedor: {producto.proveedor.nombre}</h3>

内容的提问来源于stack exchange,提问作者Andres Vilca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:03:09