Opened 10 years ago
Closed 10 years ago
#22718 closed Bug (wontfix)
django.core.files.File doesn't handle certain file-like objects (e.g. zipfile.ZipExtFile)
Reported by: | Owned by: | M. Shafiq | |
---|---|---|---|
Component: | File uploads/storage | Version: | 1.6 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
django.core.files.File checks for presence of seek() method before calling in some places but not in others causing problems with file-like objects that do not implement seek (e.g. zipfile.ZipExtFile).
For example, given myapp.models with:
class ASimpleModel(models.Model): a_file_field=models.FileField(upload_to="docs")
and a zipfile abc.zip containing a file with path "dir/file.txt", you get the following:
>>> from myapp.models import ASimpleModel >>> from zipfile import ZipFile >>> from django.core.files import File >>> zip = ZipFile("abc.zip") >>> zfile = File(zip.open("dir/file.txt") >>> m = ASimpleModel() >>> m.a_file_field.save("file.txt",zfile) Traceback (most recent call last): File "<console>", line 1, in <module> File "/usr/lib/python2.7/dist-packages/django/db/models/fields/files.py", line 90, in save self._size = content.size File "/usr/lib/python2.7/dist-packages/django/core/files/base.py", line 45, in _get_size pos = self.file.tell() UnsupportedOperation: seek >>>
Change History (5)
comment:1 by , 10 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 10 years ago
comment:4 by , 10 years ago
For me (the issue reporter) the only issue was size() failing. So I solved it by wrapping the ZipFile in another class that copied the file_size attribute of ZipFile to the _size attribute of the wrapping class, and passed through the other file-like interface methods.
You could simply check for a "file_size" attribute in _get_size(), but I agree it's probably not worth it if ZipFile is the only class that causes the issue.
comment:5 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
Closing based on last two comments.
Digged down in this issue on EuroPython 2014 Django Sprint, and If I break the
zfile = File(zip.open("dir/file.txt")
as belowand inspect on the
opened_zip_file
its an instance ofclass ZipExtFile(io.BufferedIOBase):
http://hg.python.org/cpython/file/2.7/Lib/zipfile.py#l501 which beingfile-like object
do not support seek interface on this file instance (also returnFalse
if you checkopened_zip_file.seekable()
).1 - If we want to improve the
python zipfile library
to support this interface (if necessary?) the correct fix should be done by cpython.2 - I don't see a practical example of this happening (to send
file-like
objects directly to djangoFileField
) without being involved a user's custom logic, so I think this is an individual user's problem (not Django's) to solve it by using some trick / extracting zip file in/tmp
directory of server or something like this. *I think some core django developer (if agreed?) please mark this ticket as invalid and close it.*3 - Another peer sitting around suggested to develop a
ZipFileField
but I think I don't see any usage of it currently! (if someone need it please define some standard usage, interfaces, and examples and ask for a new feature ticket and I will appreciate if you place the link of the new ticket here if you do so! I might pick that one later).