Django-Rest-Fram图像场绝对路径的获取

2024-04-25 05:58:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个周期性的celery任务,它需要在特定的json字段中存储对象的表示。在

这是简化的模型结构。 父级<;--ChildWrapper<;--子映像

所以基本上我有一个“ChildImage”模型,它引用“ChildWrapper”,而ChildWrapper又指“Parent”。在

class Parent(TimeStampedModel):
    label = models.CharField(max_length=30, unique=True)
    live_content = JSONField(blank=True, null=True)
    is_template = models.BooleanField(default=False)
    reference_image = models.ImageField(upload_to=get_web_row_reference_image_path, blank=True, null=True)
    # Around 8 Other Fields

    def __str__(self):
        return '%s' % self.label


class ChildWrapper(TimeStampedModel):
    name = models.CharField(max_length=25, blank=True, null=True)
    row = models.ForeignKey(WebRow, on_delete=models.CASCADE, related_name='web_column')
    order = models.PositiveIntegerField(default=0)
    # Around 20 Other Fields

    def __str__(self):
        return '%s' % self.name


class ChildImage(TimeStampedModel):
    image = models.ImageField(upload_to=get_web_image_path)
    column = models.ForeignKey(WebColumn, on_delete=models.CASCADE, related_name='web_image')
    # Around 10 Other Fields

    def __str__(self):
        return '%s' % self.column

这是为模型定义的序列化程序。在

^{2}$

这是一个定期的芹菜任务

@app.task(bind=True)
def update_data(self):
    # Get Parent By a condition.
    parent = Parent.objects.filter(to_update=True).first()

    parent.live_content = None
    parent.live_content = ParentSerializer(parent).data
    print(parent.live_content)
    parent.save()

上面的任务获取子图像的输出,比如这样,imagefield是相对路径而不是绝对路径。在

{
    "id": 1
    "image": '/api/col/info.jpg'
}

有没有办法得到图像场的绝对路径?在

{
    "id": 1
    "image": "http://localhost:8000/admin/media/api/col/info.jpg"
}

附言: 我不能将请求上下文作为ParentSerializer(parent,context={'Request':Request})传递给序列化程序,因为这里不涉及请求对象。在


Tags: name模型imageselfweblivetruemodels
3条回答

开始工作了

如前所述,将媒体URL添加到我的设置文件中。在

DRF似乎使用MEDIA_URL作为URL(FileField&ImageField)的默认前缀,即使对于非请求/响应流也是如此。在

因为我有一个不同的用于登台、开发和生产的设置文件,所以为每个环境设置不同的url就更容易了。在

即使我没有使用“django-versatileimagefield”库,这个建议仍然有效。在

我想你有两种方法来解决这个问题。在

首先一个是传递请求。您可以采用以下方法:

class ChildImageSerializer(serializers.ModelSerializer):
    img_url = serializers.SerializerMethodField()
    class Meta:
        model = ChildImage
        fields = '__all__'

    def get_img_url(self, obj):
        return self.context['request'].build_absolute_uri(obj.image.url)

class ChildWrapperSerializer(serializers.ModelSerializer):
    web_image = serializers.SerializerMethodField()
    class Meta:
        model = ChildWrapper
        fields = '__all__'

    def get_web_image(self, obj):
        serializer_context = {'request': self.context.get('request') }
        children = ChildImage.objects.filter(row=obj)
        serializer = ChildImageSerializer(children, many=True, context=serializer_context)
        return serializer.data

class ParentSerializer(serializers.ModelSerializer):
    web_column = serializers.SerializerMethodField()
    class Meta:
        model = Parent
        fields = '__all__'

    def get_web_column(self, obj):
        serializer_context = {'request': self.context.get('request') }
        children = ChildWrapper.objects.filter(row=obj)
        serializer = ChildWrapperSerializer(children, many=True, context=serializer_context)
        return serializer.data

这里我使用SerializerMethodField将请求传递给下一个序列化程序。在

第二种方法是使用^{}(由@dirkgroten提到)。您可以执行以下操作:

^{pr2}$

更新:我完全错过了芹菜部分。对于生产,我不认为您需要担心,因为它们在S3中,绝对路径应该来自obj.image.url。在dev和stage中,可以使用给定的示例获得绝对路径。所以,试着这样:

class ChildImageSerializer(serializers.ModelSerializer):
    img_url = serializers.SerializerMethodField()
    class Meta:
        model = ChildImage
        fields = '__all__'

    def get_img_url(self, obj):
        if settings.DEBUG:  # debug enabled for dev and stage
            return 'http://%s%s%s' % (Site.objects.get_current().domain, settings.MEDIA_URL, obj.img.url)
        return obj.img.url

或者,有一种方法可以使用芹菜中的^{}来获取请求,但我不确定是否方便您。在

我宁愿这样做:

class ChildImageSerializer(serializers.ModelSerializer):
    image = serializers.SerializerMethodField()

    def get_image(self, obj):
        if settings.DEBUG:
            host = 'http://localhost:8000'
        else:
            host = 'https://example.com'
        return host + obj.image.url

    class Meta:
        model = ChildImage
        fields = '__all__'

相关问题 更多 >