Django REST Framework and FileField absolute url

前端 未结 11 796
不知归路
不知归路 2020-12-13 02:10

I\'ve defined a simple Django app that includes the following model:

class Project(models.Model):
    name = models.CharField(max_length=200)
    thumbnail =         


        
相关标签:
11条回答
  • 2020-12-13 02:57

    check this!

    class FileFieldWithLinkRepresentation(serializers.FileField):
    
        def to_representation(self, value):
            return create_link(value.url, self.context['request'])
    

    and create_link method:

    def create_link(path: str, request: Request):
        domain = request.META['HTTP_HOST']
        if not path.startswith('/', 0, 1):
            path = '/' + path
        return request.scheme + "://" + domain + path
    

    you can use FileFieldWithLinkRepresentation in every class that needs hyperlink representation of a FileField.

    0 讨论(0)
  • 2020-12-13 03:00

    I found it annoying to write the same code for a serialized method field. If you have set correctly the MEDIA_ROOT to your S3 bucket URL, you can add a field to the serializer like:

    class ProjectSerializer(serializers.ModelSerializer):
        logo_url = serializers.URLField(read_only=True, source='logo.url')
    
        class Meta:
            model = Project
    

    logo is an ImageField in the model. it must not be nullable in order to avoid errors like ValueError: The 'img' attribute has no file associated with it.

    I only use .build_absolute_uri in a serializer methodfield to return absolute urls that use other views in my API. for example, in my project there is an URL /webviews/projects/<pk> that shows, a title and a button that collects some user input (i.e. not exactly what you would do with suffixes, as it's not a plain representation of the resource but includes some logic instead). the end point /projects/<pk>/ contains a field "webview_url" ponting there, which is generated with SerializerMethodField. it's not media.

    0 讨论(0)
  • 2020-12-13 03:04

    Try SerializerMethodField

    Example (untested):

    class MySerializer(serializers.ModelSerializer):
        thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')
    
        def get_thumbnail_url(self, obj):
            return self.context['request'].build_absolute_uri(obj.thumbnail_url)
    

    The request must available to the serializer, so it can build the full absolute URL for you. One way is to explicitly pass it in when the serializer is created, similar to this:

    serializer = MySerializer(account, context={'request': request})
    
    0 讨论(0)
  • 2020-12-13 03:09

    Just pass the context and pass request object. if you are using @api_view

    serializer = CustomerSerializer(customer, context={"request": request})
    

    For ViewSet user get_serializer_context method

    class ProjectViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer
    
    def get_serializer_context(self):
        return {'request': self.request}
    
    0 讨论(0)
  • 2020-12-13 03:10

    Just pass this "context={'request': request}" argument where you call your model serializer class to serialize the object. You can follow the below snippet to get the complete URL field.

    serialized_object = serializers.MySerializer(data, many=true, context={'request': request})
    
    0 讨论(0)
提交回复
热议问题