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

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

问题描述

在 Django 中,我有以下模型:

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)

我希望能够在模型对象/实例上替换 FileField 视频 中的文件.我写的上述方法不起作用.删除原始文件后,出现以下错误:

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.

推荐答案

您有两个选择.

我假设您的 Project 模型只是一段代码.

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

选项 1 是分解您的模型,以便 Project 没有单个文件,而是 Project 模型与 ProjectFile 模型相关联.也许一对多.一个项目和多个项目文件一样.也就是说,ProjectFile 有一个 ForeigKey to Project.

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.

然后您可以基于旧的 ProjectFile 添加新的 ProjectFile.您可以删除它们,并随心所欲地胡闹.实际上,您可以保留两个 ProjectFile 并带有当前"指示符.

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".

选项 2 是 self.video.open("w") 打开文件进行写入.重写内容就地".不是删除和替换文件,而是用新内容重写旧文件.

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天全站免登陆