嵌套序列化程序中的媒体URL不完整

时间:2019-04-28 13:34:24

标签: django django-rest-framework django-serializer django-media

我有一个django-rest-api应用程序,其模型为Record,Tag和Weight,其中Record和Tag通过Weight模型具有多对多关系:

# models.py
class Tag(models.Model):
    image = models.ImageField(upload_to='tag_images', null=True, blank=True)

class Record(models.Model):
    file = models.FileField(upload_to='record_files', null=True, blank=True)

class Weight(models.Model):
    record = models.ForeignKey(
        Record,
        related_name='weights',
        on_delete=models.CASCADE
    )
    tag = models.ForeignKey(
        Tag,
        related_name='weights',
        on_delete=models.CASCADE
    )
    value = models.IntegerField()

    class Meta:
        unique_together = ('record', 'tag',)

记录和标签模型都具有FileField / ImageField参数。在我的REST API视图中,我想显示“记录详细信息”及其完整文件url,并显示所有相关“标签”及其完整图像url。这是我的序列化器的样子:

# serializers.py
class RecordSerializer(serializers.ModelSerializer):
    tags = serializers.SerializerMethodField()

    class Meta:
        model = Record
        fields = ('id', 'file', 'tags')

    def get_tags(self, obj):
        return TagSerializer(Tag.objects.filter(weights__in=obj.weights.all()), many=True).data

class TagSerializer(serializers.ModelSerializer):

    class Meta:
        model = Tag
        fields = ('id', 'image')

问题在于,当我看到记录详细信息视图时,其文件url已完成,但标签图像url却不完整:

# record detail results
{
    "id": 1,
    "file": "http://127.0.0.1:8080/media/record_files/record00.mp3",
    "tags": [
        {
            "id": 4,
            "image": "/media/tag_images/image04.jpg"
        },
        {
            "id": 10,
            "image": "/media/tag_images/image10.jpg"
        }
    ]
}

最后,我通过创建一个单独的标签列表视图来绕过该问题,即使在我的serializers.py中没有做任何改动,URL也完整了。

# record tag list results
[
    {
        "id": 4,
        "image": "http://127.0.0.1:8080/media/tag_images/image04.jpg"
    },
    {
        "id": 10,
        "image": "http://127.0.0.1:8080/media/tag_images/image10.jpg"
    }
]

我想无论如何这都是一个更干净的rest api解决方案(尽管我很确定我将不需要分别记录详细信息及其标签)。不过,这仍然使我感到困惑,为什么当数据是嵌套序列化程序的一部分时,URL不完整。这是应该的意思还是我做错了什么?

2 个答案:

答案 0 :(得分:1)

似乎您可能找到了更好的解决方案,但以防万一您仍然感到好奇:您最初尝试的问题是将“嵌套”序列化程序调用放在了SerializerMethodField中。声明nested serializer的通常方法是在设置实际字段时初始化序列化程序。在您的情况下,它看起来像这样:

class RecordSerializer(serializers.ModelSerializer):
    tags = TagSerializer()

以这种方式执行操作时,TagSerializer可以从父序列化程序推断上下文,而该上下文的一部分就是请求。然后在to_representation的调用中build_absolute_uri中使用它来生成您希望的完整URL。

答案 1 :(得分:0)

在您的视图中像这样初始化序列化器:

var id: String { self.rawValue }

https://www.npmjs.com/package/v-tooltip