This is the model I’m using:
from django import models
class Image(models.Model):
file = models.ImageField(upload_to='uploads/images/')
Now, if I do image.file.read()
I get AttributeError: 'bytes' object has no attribute 'read'
>>> from images.models import Image
>>> img = Image.objects.first()
>>> img.file.read()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "...\.venv\lib\site-packages\django\core\files\utils.py", line 42, in <lambda>
read = property(lambda self: self.file.read)
File "...\.venv\lib\site-packages\django\core\files\utils.py", line 42, in <lambda>
read = property(lambda self: self.file.read)
AttributeError: 'bytes' object has no attribute 'read'
image.file.file
returns a bytes
object and not a File
object. I’m using Django 4.2.1 with python 3.10.7.
The following piece of code solves it, but is not a viable workaround.
import io
from images.models import Image
img = Image.objects.first()
img.file.file.file = io.BytesIO(img.file.file.file)
img.file.read() # Runs without errors
I believe that image.file.file.file
should be a File
object but it is returning a bytes
object instead. Is there something I’m missing?
jerch
May 8, 2023, 8:50am
2
What is the raw value for that entry in the database? Normally it should only contain the file path string, which the storage engine needs to locate the file to do the file API stuff underneath. It seems that you somehow ended up providing the file’s byte directly into the database. How did you populate that file entry, is there any custom logic involved (custom storage engine, a custom script creating it by other means)?
The raw DB value is uploads/images/I2524DIFKRDKPHQ3W4AZY6WW2U.webp
, the path to the file in my project’s storage. I’m using https://github.com/willmeyers/django-bunny-storage
with an overriden url
method.
from images.models import Image
img = Image.objects.first()
img.file # <ImageFile: uploads/images/I2524DIFKRDKPHQ3W4AZY6WW2U.webp>
img.file.file # <File: None>
img.file.file.file # b'\x...'
The records were created using both the admin site and a custom django-admin
command. This happens with all models where there is an ImageField
.
The project’s source code is in GitHub .
After checking my storage library’s code, I found that the error was in the library itself.
from django.core.file import File
import requests
class BunnyStorage(Storage):
def _open(self, name, mode='rb'):
resp = requests.get(self.base_url + name, headers=self.headers)
if resp.status_code == 404:
raise ValueError('File not found.')
return File(resp.content)
After replacing File
with io.BytesIO
(which is a file-like object) the error stopped being raised.