Opened 8 years ago

Closed 8 years ago

#26469 closed Bug (duplicate)

FieldFile.open() does not properly set mode when opening file

Reported by: Nathan Osman Owned by: nobody
Component: Database layer (models, ORM) Version: 1.9
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Consider the following model definition:

class Thing(models.Model):
    file = models.FileField(upload_to="things")

Let's suppose I have an existing model instance and I want to open the file for writing:

t = Thing.objects.get(pk=1)
t.file.open('wb')
t.file.write(data)

This raises an unexpected exception:

IOError: File not open for writing

Here's the source code for FieldFile.open():

def open(self, mode='rb'):
    self._require_file()
    self.file.open(mode)

The second line in the body accesses self.file - a property which is defined as follows:

def _get_file(self):
    self._require_file()
    if not hasattr(self, '_file') or self._file is None:
        self._file = self.storage.open(self.name, 'rb')
    return self._file

# ...

file = property(_get_file, ...

If self._file is None (which is the case in my example above), the storage backend is then instructed to open the file with mode 'rb' instead of the mode that was originally passed to FieldFile.open(). The newly opened File instance is returned and control resumes in FieldFile.open() which invokes the open() method on the File instance.

Here are the first few lines of File.open():

def open(self, mode=None):
    if not self.closed:
        self.seek(0)
    elif self.name and os.path.exists(self.name):
        self.file = open(self.name, mode or self.mode)
    # ...

Since the file is already open, not self.closed evaluates to True and the file remains open in read-only mode. It is not possible to write to the file.

Change History (1)

comment:1 by Tim Graham, 8 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #26398. This should be fixed in master.

Note: See TracTickets for help on using tickets.
Back to Top