在 Django Rest Framework 中访问 .data 后更新序列化程序中的值

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

我的 Post class 有一个序列化器,它有一个 image 和一个 link 属性。

media 是一个 FileFieldlink 是一个 URLField 这是一个 url 到其他地方我分享我的 post (在另一个网站。)

我想:

  1. 提交我的 post 数据(文本和图像)

  2. 正在访问已提交文件的 url 以便在其他地方共享它。

  3. 找到后更新 link 值。

这是我试过的:

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()

这引发了一个异常。说:

 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.

问题是当我使用 post.validated_data.get('media') 而不是 .data 时,它没有给我 url。它给了我一个 InMemoryUploadedFile 对象,当然,它没有任何路径和 url.

我想我可以使用 InMemoryUploadedFile 对象的 name 属性来查找 url(将在 .save() 之后创建的那个),但是当名称是重复的,磁盘中文件的真实名称和 url 与其原始名称不同(例如,name.jpgname_aQySbJu.jpg),我不能将其用于我的目的。

问题

我如何才能访问该上传文件的 URL,并在更新我的 post 后调用 save()

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

实际上,您可以使用这种方法来保存您的 post。当您通过 serializer_obj.save(**kwargs) 方法传递 link 时,它会自动将您的额外数据传递给 create(self, validated_data) 或 update(self, instance, validated_data)将您的额外数据作为字典添加到 validatad_data 中。这样您就可以在序列化程序的创建或更新方法中处理您的额外数据。

序列化器的save()方法return对应的实例。因此,您可以使用它来获取 url

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