#34674: Updating the file contents of a Django FileField during upload results
in
I/O error
------------------------------------------------+------------------------
Reporter: Jeroen Jacobs | Owner: nobody
Type: Bug | Status: new
Component: File uploads/storage | Version: 4.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
I'm trying to encrypt the contents of a file that is being uploaded. This
is the relevant code snippet:
{{{
class AppFile(models.Model):
app_file = models.FileField(upload_to=upload_to,
validators=[validate_file_size])
encrypted_data_key = models.CharField(max_length=500, blank=True)
def encrypt_file_with_data_key(self, data_key):
cipher = Fernet(data_key)
with self.app_file.open(mode='rb') as file:
file_data = file.read()
encrypted_data = cipher.encrypt(file_data)
with self.app_file.open(mode='wb') as encrypted_file:
encrypted_file.write(encrypted_data)
def save(self, *args, **kwargs):
if self._state.adding is True:
# New image being uploaded
encrypted_data_key, data_key =
self.generate_data_key_from_vault()
self.encrypted_data_key = encrypted_data_key
# Encrypt the uploaded image file
self.encrypt_file_with_data_key(data_key)
super().save(args, kwargs)
}}}
I prefer this approach as this is agnostic of the StorageProvider being
used. I also want to avoid detaching the file to a temporary folder, and
re-attach it after encryption.
However, this results in the following error:
{{{
Traceback (most recent call last):
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/views/generic/base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/views/generic/base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/views/generic/edit.py", line 184, in post
return super().post(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/views/generic/edit.py", line 153, in post
return self.form_valid(form)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/contrib/messages/views.py", line 12, in form_valid
response = super().form_valid(form)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/views/generic/edit.py", line 135, in form_valid
self.object = form.save()
^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/forms/models.py", line 548, in save
self.instance.save()
File "/Users/jeroenjacobs/PycharmProjects/myapp/mainapp/models.py", line
90, in save
self.encrypt_file_with_data_key(data_key)
File "/Users/jeroenjacobs/PycharmProjects/myapp/mainapp/models.py", line
77, in encrypt_file_with_data_key
with self.app_file.open(mode='wb') as encrypted_file:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/db/models/fields/files.py", line 80, in open
self.file.open(mode)
File "/Users/jeroenjacobs/.pyenv/versions/myapp/lib/python3.11/site-
packages/django/core/files/uploadedfile.py", line 115, in open
self.file.seek(0)
ValueError: I/O operation on closed file.
}}}
Reading the contents doesn't seem to be a problem, but writing seems to
generate an error, despite `open` being called.
--
Ticket URL: <https://code.djangoproject.com/ticket/34674>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/01070188e8d698ef-7e375f6e-52cf-4097-8da0-5e353d06a1d6-000000%40eu-central-1.amazonses.com.