将文件从一个模型复制到另一个模型

And*_*rey 20 django copy filefield

我有2个简单的模型:

class UploadImage(models.Model):
   Image = models.ImageField(upload_to="temp/")

class RealImage(models.Model):
   Image = models.ImageField(upload_to="real/")
Run Code Online (Sandbox Code Playgroud)

还有一种形式

class RealImageForm(ModelForm):
    class Meta:
        model = RealImage 
Run Code Online (Sandbox Code Playgroud)

我需要将文件从UploadImage保存到RealImage中.我怎么能这样做 下面的代码不起作用

realform.Image=UploadImage.objects.get(id=image_id).Image 
realform.save()
Run Code Online (Sandbox Code Playgroud)

Tnx寻求帮助.

amj*_*onn 30

在Gerard的解决方案的启发下,我想出了以下代码:

from django.core.files.base import ContentFile

#...

class Example(models.Model):
    file = models.FileField()

    def duplicate(self):
        """
        Duplicating this object including copying the file
        """
        new_example = Example()
        new_file = ContentFile(self.file.read())
        new_file.name = self.file.name
        new_example.file = new_file
        new_example.save()
Run Code Online (Sandbox Code Playgroud)

实际上,这将通过在文件名中添加"_1"来重命名文件,以便原始文件和文件的新副本可以同时存在于磁盘上.

  • 复制文件也可以是一行:`new_example.file = ContentFile(self.file.read(), name=self.file.name)` (4认同)
  • 我刚刚意识到,这种方式可能会占用大量内存 - 整个文件都加载到内存中。 (2认同)

Kem*_*toh 6

虽然这已经很晚了,但我会解决这个问题,

class UploadImage(models.Model):
    Image = models.ImageField(upload_to="temp/")

    # i need to delete the temp uploaded file from the file system when i delete this model      
    # from the database
    def delete(self, using=None):
        name = self.Image.name
        # i ensure that the database record is deleted first before deleting the uploaded 
        # file from the filesystem.
        super(UploadImage, self).delete(using)
        self.Image.storage.delete(name)


class RealImage(models.Model):
   Image = models.ImageField(upload_to="real/")


# in my view or where ever I want to do the copying i'll do this
import os
from django.core.files import File

uploaded_image = UploadImage.objects.get(id=image_id).Image
real_image = RealImage()
real_image.Image = File(uploaded_image, uploaded_image.name)
real_image.save()
uploaded_image.close()
uploaded_image.delete()
Run Code Online (Sandbox Code Playgroud)

如果我使用模型表来处理这个过程,我会这样做

# django model forms provides a reference to the associated model via the instance property
form.instance.Image = File(uploaded_image, os.path.basename(uploaded_image.path))
form.save()
uploaded_image.close()
uploaded_image.delete()
Run Code Online (Sandbox Code Playgroud)

请注意,我确保upload_image文件已关闭,因为调用real_image.save()将打开文件并读取其内容.这是由ImageField实例使用的任何存储系统处理的

  • 请注意,使用 image.path 不适用于任何“远距离”文件存储(如 AWS 等)。 (2认同)

ban*_*rjs 2

尝试在不使用表单的情况下执行此操作。在不知道您收到的确切错误的情况下,我只能推测表单的 clean() 方法由于 upload_to 参数不匹配而引发错误。

这让我想到了下一点,如果您尝试将图像从“temp/”复制到“real/”,您将必须执行一些文件处理来自己移动文件(如果您有 PIL,则更容易):

import Image
from django.conf import settings

u = UploadImage.objects.get(id=image_id)
im = Image.open(settings.MEDIA_ROOT + str(u.Image))
newpath = 'real/' + str(u.Image).split('/', 1)[1]
im.save(settings.MEDIA_ROOT + newpath)
r = RealImage.objects.create(Image=newpath)
Run Code Online (Sandbox Code Playgroud)

希望有帮助...