2016-02-20 8 views
9

Sono un principiante di Django e attualmente, posso costruire un modello come questo.Django serializza imagefield per ottenere l'url completo

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) 

per la foto, non mostra URL completo. Come posso mostrare l'url completo?

+0

A meno che il root_supporto è dentro la tua cartella statica, non esiste un URL diretto per il file. – jsfan

+0

provare SerializerMethodField; http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield –

risposta

25

Django non fornisce un URL assoluto per l'immagine memorizzata in un models.ImageField (almeno se non si include il nome di dominio nel MEDIA_URL, incluso il dominio non è raccomandato, a meno di si ospitano i file multimediali su un server diverso (ad es. aws)).

Tuttavia, è possibile modificare il serializzatore per restituire l'URL assoluto della foto utilizzando un numero personalizzato serializers.SerializerMethodField. In questo caso, il vostro serializzatore deve essere cambiato come segue:

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) 

anche assicurarsi di aver impostato i parametri MEDIA_ROOTand MEDIA_URL di Django e che sia possibile accedere a una foto tramite il browser http://localhost:8000/path/to/your/image.jpg.

Come palificazione sottolineato, è necessario aggiungere la richiesta, mentre inizializzazione del serializzatore nel views.py:

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

Devo modificare anche in views.py? Ho ricevuto un errore dopo aver modificato quello in Serializers.py. __init __() richiede esattamente 2 argomenti (1 dato) –

+0

Puoi aggiungere il codice relativo nel views.py? Non pensare che siano necessarie modifiche. – blacklwhite

+0

Ho aggiunto ora. Mi sto perdendo qualcosa? –

0

Per i visitatori in futuro, non c'è bisogno di aggiungere un altro campo per il serializzatore se la vista il metodo restituisce già un oggetto serializzato. L'unica cosa richiesta è di aggiungere il contesto dal momento che è necessaria per generare collegamenti ipertestuali, come dichiarato nella classe drf documentation

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

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

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)