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