web-dev-qa-db-ja.com

Django完全なURLを取得するシリアライザーImagefield

私はDjangoの初心者であり、現在、このようなモデルを構築できます。

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)

写真の場合、完全なURLは表示されません。完全なURLを表示するにはどうすればよいですか?

26
Khant Thu Linn

Djangoはmodels.ImageFieldに保存されている画像への絶対URLを提供していません(少なくとも MEDIA_URL にドメイン名を含めない場合)。別のサーバー(awsなど)でメディアファイルをホストしている場合を除き、ドメインを含めることはお勧めしません。

ただし、カスタム serializers.SerializerMethodField を使用して、シリアライザーを変更して写真の絶対URLを返すことができます。この場合、シリアライザーを次のように変更する必要があります。

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)

また、Djangoの MEDIA_ROOTおよびMEDIA_URL パラメーターを設定し、ブラウザーhttp://localhost:8000/path/to/your/image.jpgから写真にアクセスできることを確認してください。

Pilingが指摘したように、views.pyでシリアライザーを初期化するときにリクエストを追加する必要があります。

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

将来の訪問者のために、viewメソッドがすでにシリアライズされたオブジェクトを返している場合、シリアライザーに別のフィールドを追加する必要はありません。 drf documentation に記載されているように、ハイパーリンクを生成する必要があるため、必要なのはコンテキストを追加することだけです

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

シリアライザークラス

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)
9
Njeru Cyrus

上記のコードは画像がnull可能かどうかをチェックしないため、このコードを使用することをお勧めします。

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
2
Pooya Sagharchi