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

Django如何将外键关联的图片URL转为单一列表返回?

问题描述

在Django开发中,定义了Cat_Breed_Detail和Cat_Image两个模型,Cat_Image通过外键关联Cat_Breed_Detail并设置了related_name='images'。当前通过Serializer返回的响应中,images字段是嵌套的图片对象列表,需要修改为仅包含图片URL的扁平列表。

现有代码

Models.py

class Cat_Breed_Detail(models.Model):
    id = models.AutoField(primary_key=True,verbose_name="id")
    key_name = models.CharField(max_length=35,default='',null=True,verbose_name="key_name")
    display_name= models.CharField(max_length=35,default='',null=True,verbose_name="display_name")
    def __str__(self):
        return self.key_name


class Cat_Image(models.Model):
    image=models.ImageField(upload_to="ImagesCat/")
    cat=models.ForeignKey(Cat_Breed_Detail,on_delete=models.CASCADE,null=True,related_name='images')
    def image_preview(self):
        if self.image:
            return mark_safe('<img src="{0}" width="150" height="150" />'.format(self.image.url))
        else:
            return '(No image)'

Serializer.py

class CatImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Cat_Image
        fields = '__all__'
 
class CatDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = Cat_Breed_Detail
        fields = ['id','key_name','display_name','images']

View.py

class CatListCreate(ListAPIView):
    queryset = CatBreedDetails.objects.all().order_by('key_name')
    serializer_class = CatDataSerializer
    pagination_class = CustomPagination 

当前响应格式

{
    "id": 9,
    "key_name": "abyssinian",
    "display_name": "Abyssinian",
    "image": [
        {
            "id": 3,
            "image": "/media/Abyssinian_0006.jpg",
            "cat": 9
        },
        {
            "id": 4,
            "image": "/media/Abyssinian_0092.jpg",
            "cat": 9
        }
    ]
},
{
    "id": 18,
    "key_name": "american_bobtail",
    "display_name": "American Bobtail",
    "image": [
        {
            "id": 5,
            "image": "/media/American_Bobtail_0004.jpg",
            "cat": 18
        },
        {
            "id": 6,
            "image": "/media/American_Bobtail_0057.png",
            "cat": 18
        }
    ]
}

期望响应格式

{
    "id": 9,
    "key_name": "abyssinian",
    "display_name": "Abyssinian",
    "image":  ["/media/Abyssinian_0006.jpg","/media/Abyssinian_0092.jpg"]
}
解决方案

以下两种方法均可实现需求:

方法一:使用SlugRelatedField

直接在CatDataSerializer中重定义images字段,通过SlugRelatedField指定提取Cat_Image对象的image.url属性:

修改后的Serializer.py代码:

class CatDataSerializer(serializers.ModelSerializer):
    images = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='image.url'
    )

    class Meta:
        model = Cat_Breed_Detail
        fields = ['id','key_name','display_name','images']

方法二:使用SerializerMethodField

通过自定义方法生成图片URL列表,适合需要额外逻辑处理的场景(比如过滤空图片):

修改后的Serializer.py代码:

class CatDataSerializer(serializers.ModelSerializer):
    images = serializers.SerializerMethodField()

    def get_images(self, obj):
        # 遍历关联的Cat_Image对象,提取有效图片的URL
        return [image.image.url for image in obj.images.all() if image.image]

    class Meta:
        model = Cat_Breed_Detail
        fields = ['id','key_name','display_name','images']

注意事项

  • 确保Django媒体文件配置正确,保证image.url能返回可访问的有效路径。
  • 若无需过滤空图片,可去掉方法二中的if image.image判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:31:05