Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-serializer

Updating a value in serializer after accessing .data in Django Rest Framework


I have a serializer for my Post class which has a image and a link attribute.

media is an FileField and link is a URLField which is a url to somewhere else I share my post (in another website.)

I want to:

  1. Submit my post data (text, and the image)

  2. Accessing the url of submitted file to use in sharing it in another place.

  3. Updating the link value after I found it.

This is what I tried:

post = PostCreateSerializer(data=request.data, context={'request': request})
post.is_valid(raise_excpetions=True)
post.save()
media_url = post.data.get('media')
link = find_link_value(media_url)
post.link = link
post.save()

This raises an exception. says:

 You cannot call `.save()` after accessing `serializer.data`.If you need to access data before committing to the database then inspect 'serializer.validated_data' instead.

The problem is when I use post.validated_data.get('media') instead of .data, it doesn't give me the url. It gives me an InMemoryUploadedFile object, that of course, doesn't have any path and url.

I thought I could use name attribute of InMemoryUploadedFile object to find the url (the one that will be created after .save()), but when the name is duplicate, the real name of file in disk and url differs from it's original name (for example, name.jpg and name_aQySbJu.jpg) and I can't use it for my purpose.

Question

How can I have access to URL of that uploaded file, and also call save() after I updated my post?


Solution

  • The serializer's save() method return corresponding instance. So, you can use that to get the url

    post = PostCreateSerializer(data=request.data, context={'request': request})
    post.is_valid(raise_excpetions=True)
    post_instance = post.save()
    media_url = post_instance.media.url
    link = find_link_value()
    post_instance.link = link
    post_instance.save()