Django序列化器Imagefield获取完整的URL

时间:2016-02-20 11:45:15

标签: python django django-rest-framework

我是Django的初学者,目前我可以构建这样的模型。

enter image description here

models.py

class Car(models.Model):
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    photo = models.ImageField(upload_to='cars')

serializers.py

class CarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Car
        fields = ('id','name','price', 'photo') 

views.py

class CarView(APIView):
    permission_classes = ()
    def get(self, request):
        car = Car.objects.all()
        serializer = CarSerializer(car)
        return Response(serializer.data)

对于照片,它不会显示完整的网址。如何显示完整的URL?

6 个答案:

答案 0 :(得分:43)

Django没有为models.ImageField中存储的图片提供绝对网址(至少如果您不在MEDIA_URL中包含域名;不建议使用域名,除了你在不同的服务器上托管你的媒体文件(例如aws)。

但是,您可以修改序列化工具,使用自定义serializers.SerializerMethodField返回照片的绝对网址。在这种情况下,需要按如下方式更改序列化程序:

class CarSerializer(serializers.ModelSerializer):
    photo_url = serializers.SerializerMethodField()

    class Meta:
        model = Car
        fields = ('id','name','price', 'photo_url') 

    def get_photo_url(self, car):
        request = self.context.get('request')
        photo_url = car.photo.url
        return request.build_absolute_uri(photo_url)

另外,请确保您已设置Django的MEDIA_ROOTand MEDIA_URL参数,并且可以通过浏览器http://localhost:8000/path/to/your/image.jpg访问照片。

正如打桩指出的那样,你需要在views.py中初始化序列化程序时添加请求:

def my_view(request):
    …
    car_serializer = CarSerializer(car, context={"request": request})
    car_serializer.data

答案 1 :(得分:12)

对于将来的访问者,如果view方法已经返回序列化对象,则无需向序列化程序添加其他字段。唯一需要的是添加上下文,因为需要生成超链接,如drf documentation

中所述
@list_route()
def my_view(self, request):
    qs = Object.objects.all()
    return Response(MySerializer(qs, many=True, context={'request': request}).data)

答案 2 :(得分:8)

Serializer类

class CarSerializer(serializers.ModelSerializer):

  photo_url = serializers.ImageField(max_length=None, use_url=True, allow_null=True, required=False)
  class Meta:
      model = Car
      fields = ('id','name','price', 'photo_url')

查看

class CarView(APIView):

    def get(self, request, *args, **kwargs):

        queryset = Car.objects.all()

        serializer = CarSerializer(queryset, many=True, context={"request":request})

        return Response(serializer.data, status=status.HTTP_200_OK)

答案 3 :(得分:2)

最好使用此代码,因为上面的代码不会检查图像是否为空。

class CarSerializer(serializers.ModelSerializer):
      photo_url = serializers.SerializerMethodField()

      class Meta:
            model = Car
            fields = ('id','name','price', 'photo_url') 

      def get_photo_url(self, car):
            request = self.context.get('request')
            if photo and hasattr(photo, 'url'):
               photo_url = car.photo.url
               return request.build_absolute_uri(photo_url)
            else:
               return None

答案 4 :(得分:1)

serializers.py

 class BannerSerializer(serializers.ModelSerializer):
        image = serializers.SerializerMethodField()
        def get_image(self, obj):
            return self.context['request'].build_absolute_uri( obj.image.url)

views.py

            banner = Banner.objects.all()
            banner_data = BannerSerializer(banner,many=True, context={'request': request})
            data = banner_data.data
            return Response({"data":data})

答案 5 :(得分:1)

我阅读了序列化器的实现,发现最简单的方法是扩展ImageField:

Start-ThreadJob