2016-02-20 11 views
9

Jestem początkującym użytkownikiem Django i obecnie mogę skonstruować taki model.Django serializuje obraz, aby uzyskać pełny adres URL:

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) 

Na zdjęciu, nie pokazuje pełnego adresu URL. Jak mogę wyświetlić pełny adres URL?

+0

O ile MEDIA_ROOT jest w zasięgu twój statyczny folder, nie ma bezpośredniego adresu URL do pliku. – jsfan

+0

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

Odpowiedz

25

Django nie podaje bezwzględnego adresu URL do obrazu przechowywanego w pliku models.ImageField (przynajmniej, jeśli nazwa domeny nie jest podana w MEDIA_URL; w tym domena nie jest zalecana, z wyjątkiem sytuacji, w której hostujesz pliki multimedialne inny serwer (np. aws)).

Możesz jednak zmodyfikować swój serializator, aby zwrócić bezwzględny adres URL zdjęcia, używając niestandardowego serializers.SerializerMethodField. W tym przypadku, twój serializer musi zostać zmieniony w następujący sposób:

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) 

Również upewnić się, że ustawiono MEDIA_ROOTand MEDIA_URL parametry Django i że można uzyskać dostęp do fotografii za pośrednictwem przeglądarki http://localhost:8000/path/to/your/image.jpg.

palowania Jak podkreślił, trzeba dodać żądania podczas inicjalizacji serializatora w swoim views.py:

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

Czy muszę również modyfikować w views.py? Wystąpił błąd po zmianie Twojego w Serializers.py. __init __() ma dokładnie 2 argumenty (1 podany) –

+0

Czy możesz dodać powiązany kod w views.py? Nie myśl, że jakiekolwiek zmiany powinny być wymagane. – blacklwhite

+0

Dodałem już. Czy czegoś brakuje? –

0

dla przyszłych gości, nie ma potrzeby, aby dodać kolejne pole do serializatora Jeśli widok metoda już zwraca obiekt serializowany. Jedyną rzeczą, wymagane jest dodanie kontekstu, ponieważ jest ona potrzebna do wygenerowania odnośników, jak stwierdzono w klasie drf documentation

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

Serializatora

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

Zobacz

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) 
Powiązane problemy