Context: I want to take a user uploaded file, attach it to a model, change some properties and then save the object to database.
Here's some relevant code:
models.py
def file_upload_path(instance, filename):
path = os.path.join('uploaded_files', str(uuid4()))
return path
class UploadedFile(models.Model):
file_object = models.FileField(null=False, blank=False,
upload_to=file_upload_path)
def __unicode__(self):
return self.file_object.name
forms.py
class UploadFileForm(forms.ModelForm):
class Meta:
model = UploadedFile
fields = ['file_object']
views.py
def home(request):
...
if form.is_valid():
new_file = form.save(commit=True)
print new_file
...
This code prints exactly what I want, which is the file path after upload_to has been called and the file has been saved to said location (eg. "uploaded_files/b992e44e-6403-4c37-82b4-b3c403d07f79").
Now, with this views.py, things change:
views.py
def home(request):
...
if form.is_valid():
new_file = form.save(commit=False)
print new_file
# new_file_object = FileObject(os.path.abspath(new_file.file_object.url))
# new_file.mime_type = new_file_object.get_mime_type()
...
Instead of the path, I get the original filename (eg. "jnes.exe") so I can't process the file so I can get its mime type, for example, and then update the model and save it do the database.
Any ideas what I'm doing wrong? Thanks.
How I got around it:
I do the necessary model edits on the file that's still in memory/temporarily on disk since Django doesn't allow you to directly find a FileField's location until you actually save the new model instance.
forms.py
def save(self, commit=True, *args, **kwargs):
new_model = super(UploadFileForm, self).save(commit=False)
file_object = self.cleaned_data['file_object']
file_info = FileObject(file_object)
new_model.mime_type = file_info.get_mime_type()
new_model.sha256 = file_info.get_sha256()
new_model.md5 = file_info.get_md5()
if commit:
new_model.save()
return new_model
I get the hashes and mime type in FileObject's constructor by reading data from Django's UploadedFile temporary object. (thanks Daniel)