Python Django 序列化程序 Imagefield 以获取完整 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35522768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django serializer Imagefield to get full URL
提问by Khant Thu Linn
I am beginner to Django and currently, I can construct model like this.
我是 Django 的初学者,目前,我可以构建这样的模型。
models.py
模型.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
序列化程序.py
class CarSerializer(serializers.ModelSerializer):
class Meta:
model = Car
fields = ('id','name','price', 'photo')
views.py
视图.py
class CarView(APIView):
permission_classes = ()
def get(self, request):
car = Car.objects.all()
serializer = CarSerializer(car)
return Response(serializer.data)
For photo, it doesn't show full URL. How can I show full URL?
对于照片,它不显示完整的 URL。如何显示完整的 URL?
采纳答案by blacklwhite
Django is not providing an absolute URL to the image stored in a models.ImageField
(at least if you don't include the domain name in the MEDIA_URL
; including the domain is not recommended, except of you are hosting your media files on a different server (e.g. aws)).
Django是不是提供了一个绝对URL存储在图像的models.ImageField
(至少如果你不包括域名中MEDIA_URL
,包括域名,不推荐,除非你正在主持一个不同的服务器上的媒体文件(例如AWS ))。
However, you can modify your serializer to return the absolute URL of your photo by using a custom serializers.SerializerMethodField
. In this case, your serializer needs to be changed as follows:
但是,您可以修改序列化程序以使用自定义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)
Also make sure that you have set Django's MEDIA_ROOT
and MEDIA_URL
parameters and that you can access a photo via your browser http://localhost:8000/path/to/your/image.jpg
.
还要确保您已设置 DjangoMEDIA_ROOT
和MEDIA_URL
参数,并且您可以通过浏览器访问照片http://localhost:8000/path/to/your/image.jpg
。
As piling pointed out, you need to add the request while initialising the serializer in your views.py:
正如piling所指出的,您需要在views.py中初始化序列化程序时添加请求:
def my_view(request):
…
car_serializer = CarSerializer(car, context={"request": request})
car_serializer.data
回答by Hakim
For future visitors, there is no need to add another field to the serializer if the view method already returns a serialized object. The only thing required is to add the context since it is needed to generate hyperlinks, as stated in the drf documentation
对于未来的访问者,如果视图方法已经返回序列化对象,则无需向序列化程序添加另一个字段。唯一需要的是添加上下文,因为它需要生成超链接,如drf 文档中所述
@list_route()
def my_view(self, request):
qs = Object.objects.all()
return Response(MySerializer(qs, many=True, context={'request': request}).data)
回答by Njeru Cyrus
Serializer class
序列化器类
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')
View
看法
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)
回答by Pooya Sagharchi
It's better to use this code, due to the above code doesn't check the image is null able or not.
最好使用此代码,因为上面的代码不会检查图像是否为空。
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
回答by abhishek kumar
serializers.py
序列化程序.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
视图.py
banner = Banner.objects.all()
banner_data = BannerSerializer(banner,many=True, context={'request': request})
data = banner_data.data
return Response({"data":data})
回答by Sailist
I read the implement of the Serializer, and find the simplest way is to extends ImageField:
我阅读了Serializer的实现,发现最简单的方法是扩展ImageField:
from django.db import models
class ImageField(models.ImageField):
def value_to_string(self, obj): # obj is Model instance, in this case, obj is 'Class'
return obj.fig.url # not return self.url
class Class(models.Model):
name = models.CharField(max_length=50)
intro = models.CharField(max_length=200)
# fig = models.ImageField(upload_to="classes")
fig = ImageField(upload_to="classes")
def __str__(self):
return repr(self,"name")