且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django:如何替换/覆盖/更新/更改FileField的文件?

更新时间:2023-02-23 21:13:22

你有两个选择。



我将假设您的项目模型只是一段代码。



选项1是将模型断开,以使Project不具有单个文件,而是将Project模型与ProjectFile模型相关联。也许一对多。一个项目与ProjectFiles一样多。也就是说,ProjectFile有一个ForeigKey to Project。



然后你可以根据一个旧的ProjectFile添加新的ProjectFile。你可以删除它们,并且愚弄所有你想要的。实际上,您可以保留ProjectFile的当前指标。



选项2是 self.video.open(w )打开文件写入。重写内容到位。而不是删除和替换文件,请使用新的内容重写旧文件。

  with open(video_path,rb)作为来源:
self.video.open(wb)
bytes = source.read(4096)
如果字节:
self.video.write(bytes)
bytes = source.read(4096)

这可能会做你想要的。 >

是的,这似乎效率不高。真的没那么坏转换需要永远。复制需要时间。


In Django, I have the following model:

from django.db import models
from django.core.files.base import File
import os, os.path

class Project(models.Model):
    video = models.FileField(upload_to="media")

    def replace_video(self):
        """Convert video to WebM format."""
        # This is where the conversion takes place,
        # returning a path to the new converted video
        # that I wish to override the old one.
        video_path = convert_video()

        # Replace old video with new one,
        # and remove original unconverted video and original copy of new video.
        self.video.delete(save=True)
        self.video.save(os.path.basename(video_path), File(open(video_path ,"wb")), save=True)
        os.remove(video_path)

I want to be able to replace the file in the FileField video on a model object/instance. The above method I've written does not work. Once I delete the original file, I get the following error:

ValueError: The 'video' attribute has no file associated with it.

How can I replace the file with an updated one, and remove the original one (no more necessary)?

Side-Note: I have found a related issue, but with no satisfying answer.

You have two choices.

I'll assume your Project model is only a snippet of code.

Option 1 is to break your model down so that a Project does not have a single file, but rather a Project model is associated with a ProjectFile model. Perhaps one-to-many. One Project as many ProjectFiles. That is, ProjectFile has a ForeigKey to Project.

Then you can add new ProjectFile based on an old ProjectFile. You can delete them, and fool around all you want. Indeed, you can keep both ProjectFile's with an indicator of which is "current".

Option 2 is to self.video.open("w") to open the file for writing. Rewrite the contents "in place". Instead of deleting and replacing the file, rewrite the old file with the new content.

with open(video_path ,"rb") as source:
    self.video.open("wb")
    bytes= source.read(4096)
    if bytes: 
        self.video.write( bytes )
        bytes= source.read(4096)

That will probably do what you want.

Yes, it seems inefficient. It's really not that bad. The conversion takes for ever. The copy takes moments.