【问题标题】:Django, REST framework - How to ensure absolute url will be returned for image?Django,REST 框架 - 如何确保为图像返回绝对 url?
【发布时间】:2020-07-09 01:14:44
【问题描述】:

我需要 viewset 始终返回 avatar / avatar_thumbnail 图像字段的绝对 URL 作为响应,但我得到的是相对路径。我有两种这样的情况:1)在嵌套序列化程序的图像字段中,2)在视图集中,我想在检索方法中使用两个序列化程序。

models.py

class CustomUser(AbstractUser):
  avatar = ProcessedImageField(upload_to='users/',format='JPEG',options={'quality': 60})
  avatar_thumbnail = ImageSpecField(source='avatar',processors=[ResizeToFill(50, 50)],format='JPEG')

settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

urls.py

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)here

forum/api/serializers.py (嵌套序列化器)

class UserSerializer(serializers.ModelSerializer):
    avatar_thumbnail = serializers.ImageField(read_only=True)

    class Meta:
        model = CustomUser
        fields = ['id', 'username', 'avatar_thumbnail']

class ThreadSerializer(serializers.ModelSerializer):

    class Meta:
        model = Thread
        fields = ['id', 'title', 'subject', 'user']

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['user'] = UserSerializer(instance.user).data
        return representation

论坛/api/views.py

class ThreadViewSet(viewsets.ModelViewSet):
    serializer_class = ThreadSerializer
    queryset = Thread.objects.all()

对于 UserViewSet,“头像”的网址也有类似的问题。我需要绝对网址。我得到相对 url,但只有当我在视图集中覆盖检索方法时。 (我覆盖它以对作为配置文件所有者的用户使用不同的序列化程序“UserPrivateSerializer”)。对于列表,我总是得到绝对 url。

users/api/serializers.py

class UserPublicSerializer(serializers.ModelSerializer):

class Meta:
    model = CustomUser
    fields = ['id', 'username', 'avatar']

class UserPrivateSerializer(serializers.ModelSerializer):    
    email = serializers.EmailField(required=True)

    class Meta:
        model = CustomUser
        fields = ['id', 'username', 'email', 'avatar']

用户/api/views.py (这里的问题在于我想在检索方法中使用的附加序列化程序)

class UserViewSet(viewsets.ModelViewSet):
    queryset = CustomUser.objects.exclude(username='user_deleted')
    serializer_class = UserPublicSerializer
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]

def retrieve(self, request, *args, **kwargs):
    """Custom retrieve method use UserPrivateSerializer if the user object is requested by it's owner.
    """
    super().retrieve(request, *args, **kwargs)
    instance = self.get_object()
    if request.user == instance:
        serializer = UserPrivateSerializer(instance)
    else:
        serializer = UserPublicSerializer(instance)
    return Response(serializer.data, status=status.HTTP_200_OK)

【问题讨论】:

    标签: python django django-rest-framework django-imagekit


    【解决方案1】:

    我发现当我向序列化程序添加上下文时问题已经解决了。

    论坛/api/serializers.py

    class ThreadSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Thread
            fields = ['id', 'title', 'subject', 'user']
    
        def to_representation(self, instance):
            representation = super().to_representation(instance)
            representation['user'] = UserSerializer(instance.user, context=self.context).data
            return representation
    

    users/api/views.py

    class UserViewSet(viewsets.ModelViewSet):
        queryset = CustomUser.objects.exclude(username='user_deleted')
        serializer_class = UserPublicSerializer
        permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
    
        def retrieve(self, request, *args, **kwargs):
            super().retrieve(request, *args, **kwargs)
            instance = self.get_object()
            if request.user == instance:
                serializer = UserPrivateSerializer(instance, context={'request': request})
            else:
                serializer = UserPublicSerializer(instance, context={'request': request})
            return Response(serializer.data, status=status.HTTP_200_OK)
    

    我在这里找到了答案:Django REST Framework and FileField absolute url “请求必须对序列化程序可用,因此它可以为您构建完整的绝对 URL。一种方法是在创建序列化程序时显式传递它”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 2015-09-06
      • 2016-05-30
      • 2019-12-11
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多