Я сам недавно столкнулся с этой проблемой и решил ее примерно так:

ngo у меня есть следующая модель:

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видео на модельном объекте / экземпляре. Вышеописанный метод не работает. Как только я удаляю исходный файл, я получаю следующую ошибку:

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

Как я могу заменить файл на обновленный и удалить оригинальный (больше не нужно)?

Примечание: Я нашелсвязанная проблема, но без удовлетворительного ответа.

Ответы на вопрос(2)

Решение Вопроса

Я приму вашеProject Модель - это всего лишь фрагмент кода.

Вариант 1 состоит в том, чтобы разбить вашу модель так, чтобы у проекта не было ни одного файла, а модель проекта была бы связана с моделью ProjectFile. Возможно, один ко многим. Один проект как много ProjectFiles. То есть ProjectFile имеет ForeigKey для Project.

Затем вы можете добавить новый ProjectFile на основе старого ProjectFile. Вы можете удалить их, и дурачиться все, что вы хотите. Действительно, вы можете сохранить оба ProjectFile с индикатором, который является «текущим».

Вариант 2 заключается вself.video.open("w") открыть файл для записи. Перепишите содержимое "на месте". Вместо того, чтобы удалять и заменять файл, переписать старый файл с новым содержимым.

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)

Это, вероятно, будет делать то, что вы хотите.

Да, это кажется неэффективным. Это действительно не так уж и плохо. Преобразование занимает вечность. Копия занимает минуты.

 Ory Band25 янв. 2011 г., 12:21
Вариант 1 действительно звучит как хорошая идея. Спасибо!

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.
        old_path = self.video.path
        self.video.save(os.path.basename(video_path), File(open(video_path ,"wb")), save=True)
        os.remove(video_path)
        os.remove(old_path)

Ваш ответ на вопрос