如何在django模型中获取静态默认图像的完整URL

时间:2017-06-19 23:19:15

标签: django django-models django-rest-framework

我有一个接受不需要的图像的模型。

我试图提供默认图片的链接,以便当用户稍后请求模型时,我可以向他们发送默认图片。

我使用的是DRF,因此我无法访问视图中的reverse;基于this response我试图在模型中实现功能。

# models.py
class Widget(models.Model):
...    
    def image_url(self):

        '''
        Returns the url of the image for the model instance.

        If no image is found, return the path to the default meal image.
        '''
        if self.image and hasattr(self.image, 'url'):
            return self.image.url
        else:
            return settings.STATIC_URL + 'img/default/meal.png'

在我的序列化程序中,我只是添加字段而不是图像:

#serializers.py
class WidgetSerializer(serializers.HyperlinkedModelSerializer):
...
    class Meta:
        model = Widget
        fields = ('image_url',
        ...
        )

然而,这当然只给出了图像的相对路径,/static/img/default/meal.png而不是http://localhost:8010/static/img/default/meal.png

如何获取模型中url的基本名称,以便我可以使用完整的url进行响应?这甚至是正确的方法吗?

另外,作为附注,我刚刚在浏览器中访问了http://localhost:8010/static/img/default/meal.png,并且说无法找到图片。有关于此的任何想法吗?

- 编辑 -

我想知道如何在视图中使用它。截至目前,它只适用于详细视图,我必须将相同的代码复制到列表视图中才能工作,我不愿意为干燥原因做这些代码。

理想情况是在序列化程序中获取默认图像的完整网址,但我仍然不确定如何访问那里的请求对象。

# views.py
class WidgetDetail(APIView):

    def get_object(self, pk):
        try:
            return Widget.objects.get(pk=pk)
        except Widget.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        widget = self.get_object(pk)
        serializer = WidgetSerializer(
            widget,
            context={'request': request},
        )
        serialized_data = serializer.data

        if not widget.image:
            serialized_data['image'] = request.build_absolute_uri(
                settings.STATIC_URL + 'img/default/widget.png')
            # print(serialized_data['image'])

        return Response(serialized_data)
...

class WidgetList(APIView):

    def get(self, request, format=None):
        widgets = Widget.objects.all()
        serializer = WidgetSerializer(
            widgets,
            many=True,
            context={'request': request},
        )
        #... Would need to replace null urls here....
        return Response(serializer.data)

但是,由于我将上下文传递给序列化程序,我应该可以在那里访问它,不是吗?

1 个答案:

答案 0 :(得分:2)

view.py:

data = WidgetSerializer(wight, context={'request': request}).data

serializer.py

class WidgetSerializer(serializers.HyperlinkedModelSerializer):
...
    class Meta:
        model = Widget
        fields = ('image',
        ...
        )

将<{1}}添加到序列化程序中即可获得图片的完整路径。更多信息here

如果要在序列化程序中设置它:

context={'request': request}

model.py

class WidgetSerializer(serializers.HyperlinkedModelSerializer):
    image = serializers.SerializerMethodField()
    class Meta:
        model = Widget
        fields = ('image',
        ...
        )

    def get_image(self, instance):
        request = self.context.get('request')
        return request.build_absolute_uri(instance.get_image())