Django:如何替换/覆盖/更新/更改FileField的文件? [英] Django: How to replace/overwrite/update/change a file of FileField?

查看:1018
本文介绍了Django:如何替换/覆盖/更新/更改FileField的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django中,我有以下模型:

  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):
将视频转换为WebM格式。
#这是转换发生的地方,
#返回一个路径新的转换视频
#,我想覆盖旧的。
video_path = convert_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)

我想要能够替换模型对象/实例上的FileField 视频中的文件。我写的上述方法不行。一旦我删除原始文件,我会收到以下错误:

  ValueError:video属性没有与之关联的文件。 

如何用更新的文件替换文件,并删除原始文件(不再需要) ?



侧注:我找到了一个相关问题,但没有令人满意的答案。

解决方案

你有两个选择。



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



选项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.

这篇关于Django:如何替换/覆盖/更新/更改FileField的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆