首页 > 解决方案 > DRF + Serializer 从多个模型返回自定义数据

问题描述

与这个问题相关,我试图在 DRF 的一个查询中返回来自多个模型的数据。

class Artist(models.Model):
    artist_name = models.CharField(max_length=100)

class Genre(models.Model):
    genre_name = models.CharField(max_length=100)

class Album(models.Model):
    album_name = models.CharField(max_length=100)
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    genre = models.ForeignKey(Genre, on_delete=nodels.CASCADE)

我想返回所有艺术家的专辑和流派的所有选项的 JSON 列表。

就像是:

{
    "genres": ["techno", "rap", "rock", ...],
    "albums": ["nevermind", "collection", "fragile", ...]
}

我创建了一个自定义序列化程序:

class InfoSerializer(serializers.Serializer):
    albums = serializers.CharField()
    genres = serializers.CharField()

    class Meta:
        fields = ["albums", "genres"]

和一个视图集:

class OptionsViewSet(ViewSet):
    serializer_class = InfoSerializer

    def list(self, request):
        options = [{"albums": Album.objects.all()},
                   {"genres": Genre.objects.all()}]
        results = InfoSerializer(options, many = True)
        results.is_valid()
        return Response(results.data)

我不断收到错误消息:

尝试获取序列化程序上的字段值时出现albumsKeyError InfoSerializer ...

标签: djangodjango-rest-frameworkdjango-serializer

解决方案


您正在为 InfoSerializer 提供选项,并且该序列化程序假定options具有名为专辑和流派的属性。由于它没有,因此会引发错误。请参阅drf 文档

您的视图集的设计看起来像您正在返回多个实例,但实际上您返回的是一个只有两个键的字典。专辑和流派是相互独立的,所以返回一个数组 withmany=True在这里没有任何意义。

我建议您在 APIView 中返回类似的内容。此外,您只能从数据库中检索album_nameand genre_name,这将使其性能更高。

{
    "albums": list(Album.objects.all().values_list('album_name', flat=True)),
                   
    "genres": list(Genre.objects.all().values_list('genre_name', flat=True))
}

推荐阅读