将文件从已保存的FileField复制到Django中的UploadedFile

时间:2011-04-29 00:24:07

标签: django file-upload filefield django-file-upload

我需要保存文件,而不是来自request.FILES,而是来自另一个保存的记录。

以下是模型记录的代码:

class Foo(models.Model)
    slug = models.SlugField()

class FooFile(models.Model):
    name = models.CharField(max_length=100)
    file = models.FileField(upload_to='foo_folder')
    foo = models.ForeignKey(Foo, related_name='files')

class RealRecord(models.Model):
    slug = models.SlugField()
    awesome_file=models.FileField(upload_to='awesome')
    mediocre_file=models.FileField(upload_to='mediocre')

视图(在本例中为MyForm是保存到RealRecord的模型表单):

def example(request, record=1, template_name="form.html")
    foo_obj = Foo.objects.get(pk=record)
    SAVED_FILES = {}
    for file in foo_obj.files.all():
         SAVED_FILES[file.name]=file.file
    if request.method == 'POST':
        form = MyForm(data=request.POST, files=SAVED_FILES)
        if form.is_valid():
            form.save() 
            # rest of view
    else:
        form = MyForm()
    return render(request, template_name, locals())

所以事情基本上是FieldFile被用作UploadedFile对象。

每个Foo都会有一个FooFile记录,其名称为awesome_file,另一个记录的名称为mediocre_file,与RealRecord中的必填字段相匹配。

疯狂的是,这完全有效。 然而,问题是在创建的结果记录中,awesome_file和mediocre_file的路径都在“foo_folder”中。但我不希望文件在“foo_folder”中,我希望它们位于我为RealRecord中的每个字段指定的路径中。

所以我想我想知道我可以对来自FieldFile的{​​{1}}值做些什么,这样他们的行为就像传统的UploadedFile一样,得到FooFieldupload_to各自领域的价值观。

1 个答案:

答案 0 :(得分:1)

Awww ...你们!我真的希望有人会想出答案。无论如何,我能够提出自己的解决方案;不确定它是否是最佳的但是有效。

我对FooFile做了一个小模式,因此它还存储了上传文件的content_type:

class FooFile(models.Model):
    name = models.CharField(max_length=100)
    file = models.FileField(upload_to='foo_folder')
    content_type = models.CharField(max_length=254) # max length given by RFC 4288 
    foo = models.ForeignKey(Foo, related_name='files')

然后,在视图中,我为每个SimpleUploadedFile记录创建一个FooFile对象:

from django.core.files.uploadedfile import SimpleUploadedFile
import os

def example(request, record=1, template_name="form.html")
    foo_obj = Foo.objects.get(pk=record)
    SAVED_FILES = {}
    for saved_file in foo_obj.files.all():
        SAVED_FILES[file.name]=SimpleUploadedFile(os.path.basename(saved_file.file.path), saved_file.file.read(), saved_file.content_type)
    if request.method == 'POST':
        form = MyForm(data=request.POST, files=SAVED_FILES)
        if form.is_valid():
            form.save() 
            # rest of view
    else:
        form = MyForm()
    return render(request, template_name, locals())