为了账号安全,请及时绑定邮箱和手机立即绑定

在Django Rest Framework Serializer中,如何获取图像的完整路径?

在Django Rest Framework Serializer中,如何获取图像的完整路径?

暮色呼如 2021-11-16 15:44:24
在我的项目中,我想使用 Serializer 类获取图像的完整路径。当我使用 ViewSet 类时,它似乎得到了正确的结果。但是当使用 APIView 类时,它没有得到我需要的。# the modelclass UserAccount(models.Model):    ...    icon = models.ImageField(upload_to='icon/user')# the serializerclass UserSerializer(serialziers.ModelSerializer):    class Meta:        model = UserAccount        fields = (..., 'icon')使用视图集# viewsetclass UserViewSet(viewsets.ModelViewSet):    ...    serializer_class = UserSerializer# result# {..., 'icon': 'http://127.0.0.1:8000/media/icon/user/filename'}使用 APIViewclass UserView(APIView):...def get(self, request):    ...    userAccount = user.userAccount    serializer = UserSerializer(userAccount)    return Response(serializer.data)# result# {..., 'icon': '/media/icon/user/filename'}我应该怎么做才能在 APIView 中获取图像的完整路径?
查看完整描述

2 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

您需要添加额外的字段SerializerMethodField:


class UserSerializer(serializers.ModelSerializer):

    icon_url = serializers.SerializerMethodField()


    class Meta:

        model = UserAccount

        fields = (..., 'icon_url') 


    def get_icon_url(self, user_account):

        request = self.context.get('request')

        icon_url = user_account.icon.url

        return request.build_absolute_uri(icon_url)

并添加request到上下文中:


def get(self, request):

    ...

    userAccount = user.userAccount

    serializer = UserSerializer(userAccount, context={'request':request})

    return Response(serializer.data)


查看完整回答
反对 回复 2021-11-16
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

请参阅更新的部分。


出于同样的目的,我创建了一个可以在序列化程序类上继承的可重用 mixin。


from django.db.models import FileField, ImageField


def get_full_url(request, path):

    """Get full url with respect to current scheme"""

    url = request.scheme + "://" + request.get_host() + path

    return url



class FileFullPathSerializerMixins:


    def to_representation(self, instance):

        request = self.context['request']

        data = super().to_representation(instance)

        for field in instance._meta.fields:

            # returns the full file path for the below instance db cols

            if field.__class__ in [FileField, ImageField]:

                field_val = getattr(instance, field.name).name

                if field_val:

                    data[field.name] = get_full_url(request, field_val)

        return data

用法示例:


class UserProfileSerializer(FileFullPathSerializerMixins,serializers.ModelSerializer):

    

    class Meta:

        model = User

        fields = ('first_name', 'last_name', 'avatar', 'email')

        extra_kwargs = {

            'email': {'read_only': True}

        }

注意事项:确保将请求作为视图集中的上下文传递为:


class UserProfileViewSet(viewsets.ModelViewSet):

        serializer_class = UserProfileSerializer


    def get_serializer_context(self):

        context = super(UserProfileViewSet, self).get_serializer_context()

        context.update({"request": self.request})

        return context

更新: 如果您在序列化程序字段中使用 FileField 或 ImageField。无需修改实际响应。


class FooSerializer(serializers.Serializer):

    image = serializers.ImageField(source='image_field')

    file = serializers.ImageField(source='file_field')

to_representation如果您在序列化程序中使用 ImageField 或 FileField,则无需使用方法手动修改 api 响应的内部表示。只需将请求作为上下文传递给序列化程序就可以正常工作,否则上述方法效果很好。


查看完整回答
反对 回复 2021-11-16
  • 2 回答
  • 0 关注
  • 270 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信