3π
If you go through the source code in class S3BotoStorageFile
and function write
, the header is updated from only 2 places,
upload_headers.update(self._storage.headers)
whereself._storage.headers
is taken fromAWS_HEADERS
self._storage.default_acl
And in function _flush_write_buffer
only self._storage.headers
is considered. Check for the line headers = self._storage.headers.copy()
So updating test.key.content_type
will not work.
Instead of test.key.content_type = "text/plain"
at In [9]:
try using test._storage.headers['Content-Type'] = 'text/plain'
, it should work.
2π
Now you can use django-storages >= 1.4
and it automatically guesses the mime types.
- Iphone push notifications passphrase issue (pyAPns)
- AttributeError: 'NoneType' object has no attribute 'attname' (Django)
- How to compare version string ("x.y.z") in MySQL?
- Django Rest Framework APIRequestFactory request object has no attribute 'query_params'
2π
This is for Boto3 ONLY, not Boto. If you would like to set those headers, you will need to access the object like so, file_ is refereing to a FileField with storage setup to be using Boto3 from django-storages:
file_.storage.object_parameters = { 'ContentType': 'text/plain' }
NOTE: it requires header names to be camelcase, so Content-Type
= ContentType
, Content-Dispostion
= ContentDispostion
etc. Hope this helps!
- Generating single access token with Django OAuth2 Toolkit
- How to assert django uses particular template in pytest
- How do you add a non-editable field to a custom admin form in Django
- Logging formatters in django
1π
According to this answer, the Content-Type isnβt metadata but rather headers that you set up when you upload the file.
- How do I get the django HttpRequest from a django rest framework Request?
- Django-templates: Why doesn't {% if "string"|length > 10 %} work at all?
- How can I create a case-insensitive database index in Django?
- Django β rendering many templates using templatetags is very slow
0π
Iβve had a similar issue β I wanted to set my header for all the files uploaded to S3 using django-storages
, without relying on the default library approach which is guessing mime type based on the filename.
Please note that you can tweak the way how the header is set and you donβt have to have it fixed like I have (my case was specific).
This is what worked for me:
- Implement custom file manager:
import os
from storages.backends.s3boto3 import S3Boto3Storage
class ManagedS3BotoS3Storage(S3Boto3Storage):
def _save(self, name, content):
cleaned_name = self._clean_name(name)
name = self._normalize_name(cleaned_name)
params = self._get_write_parameters(name, content)
content_type = "application/octet-stream". # Content-Type that I wanted to have for each file
params["ContentType"] = content_type
encoded_name = self._encode_name(name)
obj = self.bucket.Object(encoded_name)
if self.preload_metadata:
self._entries[encoded_name] = obj
content.seek(0, os.SEEK_SET)
obj.upload_fileobj(content, ExtraArgs=params)
return cleaned_name
- Use
ManagedS3BotoS3Storage
in model:
class SomeCoolModel(models.Model):
file = models.FileField(
storage=ManagedS3BotoS3Storage(bucket="my-awesome-S3-bucket"),
upload_to="my_great_path_to_file",
)
- Run
python manage.py makemigrations
.
Thatβs it, after this all files that I had was uploaded with Content-Type: "application/octet-stream
- Gunicorn: Can't connect to gunicorn.sock
- Django Rest Framework Testing response headers
- How to create custom groups in django from group
- How to access named url arguments in permissions with Django REST Framework?