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

Django DRF序列化关联URLField 如何返回纯URL列表而非字典对象

问题描述

基于Django REST Framework序列化器开发时,需要实现模型存储用户搜索产生的URL列表,通过序列化器返回对应URL的组合内容。目前参考官方文档及相关社区问答已完成基础功能开发,但返回格式不符合预期:需要解包DRF响应中嵌套的字典列表。

当前API输出效果:
当前API输出示例

当前返回的links字段为带link键的字典列表,结构为[{"link": "url1"}, {"link": "url2"}],预期links字段直接输出纯URL字符串列表,结构为["url1", "url2"]。

现有代码

models.py(精简版本)

class User(AbstractUser):
    pass

class Combo(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='searches')
    updated = models.DateTimeField(auto_now = True)
    created = models.DateTimeField(auto_now_add = True)

class ComboLink(models.Model):
    combo = models.ForeignKey('Combo', on_delete=models.CASCADE, related_name='links')
    link = models.URLField(null=True, blank=True)

serializers.py

class ComboLinkSerializer(ModelSerializer):
    class Meta:
        model = ComboLink
        fields = ['link']

class ComboSerializer(ModelSerializer):
    links = ComboLinkSerializer(many=True)
    class Meta:
        model = Combo
        fields = ['user', 'id', 'created', 'links']
解决方案

返回嵌套字典的核心原因是使用了完整的模型序列化器做关联嵌套,该序列化器默认会将每个关联对象序列化为包含对应字段的字典。要实现纯字符串列表输出,有两种可直接落地的实现方案:

  • 方案1:使用SlugRelatedField(优先选择,代码最简洁)
    无需单独定义ComboLinkSerializer,直接在ComboSerializer中使用SlugRelatedField指定提取关联对象的link字段值即可。
    修改后的serializers.py代码:

    from rest_framework.serializers import ModelSerializer, SlugRelatedField
    
    class ComboSerializer(ModelSerializer):
        links = SlugRelatedField(
            many=True,
            read_only=True,
            slug_field='link'
        )
        class Meta:
            model = Combo
            fields = ['user', 'id', 'created', 'links']
    

    该配置会自动遍历所有关联的ComboLink对象,提取每个对象的link属性值,直接返回纯字符串格式的URL列表。如果需要支持写入操作(创建/更新Combo时同步提交URL列表生成关联记录),只需移除read_only=True,补充对应create/update方法处理关联对象的创建逻辑即可。

  • 方案2:重写关联序列化器的to_representation方法
    如果后续需要扩展ComboLink的序列化逻辑,可以保留原有ComboLinkSerializer,重写其to_representation方法,直接返回link字段值而非字典结构:

    class ComboLinkSerializer(ModelSerializer):
        class Meta:
            model = ComboLink
            fields = ['link']
        
        def to_representation(self, instance):
            return instance.link
    
    class ComboSerializer(ModelSerializer):
        links = ComboLinkSerializer(many=True)
        class Meta:
            model = Combo
            fields = ['user', 'id', 'created', 'links']
    

两种方案最终返回效果完全一致,无特殊扩展需求时优先选择方案1,减少冗余代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:48:16