How to assign a local file to the FileField in Django?
Question:
I was trying to assign a file from my disk to the FileField, but I have this error:
AttributeError: ‘str’ object has no attribute ‘open’
My python code:
pdfImage = FileSaver()
pdfImage.myfile.save('new', open('mytest.pdf').read())
and my models.py
class FileSaver(models.Model):
myfile = models.FileField(upload_to="files/")
class Meta:
managed=False
Thank you in advance for your help
Answers:
Django uses it’s own file type (with a sightly enhanced functionality). Anyway Django’s file type works like a decorator, so you can simply wrap it around existing file objects to meet the needs of the Django API.
from django.core.files import File
local_file = open('mytest.pdf')
djangofile = File(local_file)
pdfImage.myfile.save('new', djangofile)
local_file.close()
You can of course decorate the file on the fly by writing the following (one line less):
pdfImage.myfile.save('new', File(local_file))
If you don’t want to open the file, you can also move the file to the media folder and directly set myfile.name with the relative path to MEDIA_ROOT :
import os
os.rename('mytest.pdf', '/media/files/mytest.pdf')
pdfImage = FileSaver()
pdfImage.myfile.name = '/files/mytest.pdf'
pdfImage.save()
if you are getting error like:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position...
then you have to open the file in binary mode: open("mytest.pdf", "rb")
full example:
from django.core.files import File
pdfImage = FileSaver()
pdfImage.myfile.save('new.pdf', File(open('mytest.pdf','rb')))
If you want to upload a local file in django, you can do this
from django.core.files import File
file = open(filepath, 'rb')
file_to_upload = File(file, name=f'{your_desired_name}')
file.close()
Now you can pass the file to django rest serializer to upload or whatever your use-case is. If passing this file to serializer, be sure to close it after it has been passed to serializer.
Note: The filepath here can be django’s temporary file or any stored file.
I was trying to assign a file from my disk to the FileField, but I have this error:
AttributeError: ‘str’ object has no attribute ‘open’
My python code:
pdfImage = FileSaver()
pdfImage.myfile.save('new', open('mytest.pdf').read())
and my models.py
class FileSaver(models.Model):
myfile = models.FileField(upload_to="files/")
class Meta:
managed=False
Thank you in advance for your help
Django uses it’s own file type (with a sightly enhanced functionality). Anyway Django’s file type works like a decorator, so you can simply wrap it around existing file objects to meet the needs of the Django API.
from django.core.files import File
local_file = open('mytest.pdf')
djangofile = File(local_file)
pdfImage.myfile.save('new', djangofile)
local_file.close()
You can of course decorate the file on the fly by writing the following (one line less):
pdfImage.myfile.save('new', File(local_file))
If you don’t want to open the file, you can also move the file to the media folder and directly set myfile.name with the relative path to MEDIA_ROOT :
import os
os.rename('mytest.pdf', '/media/files/mytest.pdf')
pdfImage = FileSaver()
pdfImage.myfile.name = '/files/mytest.pdf'
pdfImage.save()
if you are getting error like:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position...
then you have to open the file in binary mode: open("mytest.pdf", "rb")
full example:
from django.core.files import File
pdfImage = FileSaver()
pdfImage.myfile.save('new.pdf', File(open('mytest.pdf','rb')))
If you want to upload a local file in django, you can do this
from django.core.files import File
file = open(filepath, 'rb')
file_to_upload = File(file, name=f'{your_desired_name}')
file.close()
Now you can pass the file to django rest serializer to upload or whatever your use-case is. If passing this file to serializer, be sure to close it after it has been passed to serializer.
Note: The filepath here can be django’s temporary file or any stored file.