Django serializador Imagefield para obtener la URL completa

Soy principiante en Django y actualmente, puedo construir un modelo como este.

introduzca la descripción de la imagen aquí

modelos.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') 

vistas.py

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

Para la foto, no muestra la URL completa. ¿Cómo puedo mostrar la URL completa?

Django no proporciona una URL absoluta a la imagen almacenada en los models.ImageField (al menos si no incluye el nombre de dominio en MEDIA_URL ; no se recomienda incluir el dominio, excepto si está alojando sus archivos de medios en una MEDIA_URL diferente). servidor (por ejemplo, aws)).

Sin embargo, puede modificar su serializador para devolver la URL absoluta de su foto usando un serializers.SerializerMethodField personalizado. serializers.SerializerMethodField . En este caso, su serializador debe cambiarse de la siguiente manera:

 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) 

También asegúrese de haber configurado los parámetros MEDIA_ROOT y MEDIA_URL Django y que pueda acceder a una foto a través de su navegador http://localhost:8000/path/to/your/image.jpg .

Como se indica en el astackmiento, debe agregar la solicitud mientras inicializa el serializador en su views.py:

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

Para futuros visitantes, no es necesario agregar otro campo al serializador si el método de vista ya devuelve un objeto serializado. Lo único que se requiere es agregar el contexto, ya que se necesita para generar hipervínculos, como se indica en la documentación de drf

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

Clase serializador

 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') 

Ver

 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) 

Es mejor usar este código, ya que el código anterior no comprueba si la imagen es nula o no.

 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