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

发布于 2024-11-04 04:14:12 字数 1595 浏览 5 评论 0原文

我需要保存文件,不是来自 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 将有一个名为 awesome_fileFooFile 记录和另一个名为 mediocre_file 的记录,与RealRecord 中的必填字段。

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

所以我想我想知道我可以对来自 FooFieldFieldFile 值做什么,以便它们的行为像传统的 UploadedFile 并获取 upload_to和各自字段的 path 值。

I need to save files, not from request.FILES, but from another saved record.

Here's the code for the model record:

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')

And the view (in this case MyForm is a model form that saves to 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())

So the thing is basically a FieldFile is being used as an UploadedFile object.

Each Foo will have a FooFile record with the name awesome_file and another with the name mediocre_file, matching up with the required fields in RealRecord.

The crazy thing is, this totally validates. However, the problem is that in the resulting record that is created, both awesome_file and mediocre_file have their path in "foo_folder". But I don't want the files in "foo_folder", I want them to be in the path that I specified for each field in RealRecord.

So I guess I am wondering what I can do to the FieldFile values coming from FooField so that they behave like a traditional UploadedFile and get the upload_to and path values of their respective fields.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

棒棒糖 2024-11-11 04:14:14

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

我对 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')

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

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())

Awww... you guys! I was really hoping someone would come up with an answer. Anyway, I was able to come up with my own solution; not sure if it's the optimal one but it works.

I made a slight mod to FooFile so it also stores the content_type of the uploaded file:

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')

and then, in the view, I create a SimpleUploadedFile object for each FooFile record:

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())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文