Je suis débutant à Django et actuellement, je peux construire un modèle comme celui-ci.
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)
Pour la photo, elle n'affiche pas l'URL complète. Comment afficher l'URL complète?
Django ne fournit pas d'URL absolue à l'image stockée dans un models.ImageField
(au moins si vous n'incluez pas le nom de domaine dans le MEDIA_URL
; il n'est pas recommandé d'inclure le domaine, sauf si vous hébergez vos fichiers multimédias sur un autre serveur (par exemple, aws)).
Cependant, vous pouvez modifier votre sérialiseur pour renvoyer l'URL absolue de votre photo en utilisant un personnalisé serializers.SerializerMethodField
. Dans ce cas, votre sérialiseur doit être modifié comme suit:
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)
Assurez-vous également que vous avez défini Django MEDIA_ROOT
et MEDIA_URL
paramètres et que vous pouvez accéder à une photo via votre navigateur http://localhost:8000/path/to/your/image.jpg
.
Comme l'a souligné l'empilement, vous devez ajouter la demande lors de l'initialisation du sérialiseur dans vos vues.py:
def my_view(request):
…
car_serializer = CarSerializer(car, context={"request": request})
car_serializer.data
Pour les futurs visiteurs, il n'est pas nécessaire d'ajouter un autre champ au sérialiseur si la méthode view renvoie déjà un objet sérialisé. La seule chose requise est d'ajouter le contexte car il est nécessaire de générer des hyperliens, comme indiqué dans la documentation drf
@list_route()
def my_view(self, request):
qs = Object.objects.all()
return Response(MySerializer(qs, many=True, context={'request': request}).data)
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)
Il est préférable d'utiliser ce code, car le code ci-dessus ne vérifie pas que l'image est nulle ou non.
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