12👍
I know this question is already answered, but just in case someone is looking for what I needed when I stumbled across this question…
I found for large queries that pulling the url off of the model instance (report.file.url
) was resulting in terrible performance in cases where I need to pull a lot of records, because Django does a database query per record when accessing model fields this way. Here is an example implementation of an alternate method where you can do the entire query up front and still get the url if you need it.
from django.core.files.storage import get_storage_class
from . import models
# instance of the current storage class
media_storage = get_storage_class()()
# grabs all of my reports at once and stores them in a list of dicts
# instead of separate Report instances
report_list = models.Report.objects.values()
# stick the urls into the my records
report_list = [
{**report, "url": media_storage.url(report["file"])}
for report in report_list
]
5👍
The file should be located at :
cache = cache.objects.get(identifier=identifier)
cache_file = cache.cache_file
cache_file_url = cache.cache_file.url
Call this this to get the complete S3 URL but you should have set up django storages to get this.
- Django QuerySet object has no attribute 'objects
- Django custom login page
- Correct setup of django redis celery and celery beats
- Passing arguments to management.call_command on a django view
- Using a custom form in a modelformset factory?
0👍
Although we now have 2 good answers, it’s worth just exploring what is under the hood when it comes to the media_storage.url()
call:
***N.B. Assume we have django-storages
installed in settings.py
and have the correct settings, for example:
# Defualt File Storage (Remote/Cloud Storage Service)
# https://docs.djangoproject.com/en/3.0/ref/settings/#default-file-storage
DJANGO_REMOTE_STORAGE_ON = bool(os.environ.get('DJANGO_REMOTE_STORAGE_ON'))
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' if DJANGO_REMOTE_STORAGE_ON else 'django.core.files.storage.FileSystemStorage'
if DEFAULT_FILE_STORAGE == 'storages.backends.s3boto3.S3Boto3Storage':
AWS_STORAGE_BUCKET_NAME = os.environ.get('DJANGO_AWS_STORAGE_BUCKET_NAME')
AWS_ACCESS_KEY_ID = os.environ.get('DJANGO_AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('DJANGO_AWS_SECRET_ACCESS_KEY')
AWS_S3_REGION_NAME = os.environ.get('DJANGO_AWS_S3_REGION_NAME')
AWS_S3_ENDPOINT_URL = os.environ.get('DJANGO_AWS_S3_ENDPOINT_URL')
AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', }
AWS_DEFAULT_ACL = 'public-read'
AWS_BUCKET_ACL = 'public-read'
AWS_IS_GZIPPED = True
AWS_S3_USE_SSL = True
AWS_QUERYSTRING_AUTH = False
from django.core.files.storage import get_storage_class
media_storage = get_storage_class()()
// Assume we know some sort of ID:
id = 1
// Retrieve the object instance from the ID (or other attribute field)
obj = Object.objects.get(id=id)
// Assuming we have some file field called "file":
boto_s3_url = media_storage.url(name=obj.file.name)
This ensures that regardless of our storage method, we’ll always retrieve the absolute URI location, e.g., "https://<AWS_S3_REGION_NAME>.<AWS_S3_ENDPOINT_URL>/<AWS_STORAGE_BUCKET_NAME>/<UPLOADS_TO>/<FILENAME>"
.
e.g., https://nyc3.digitaloceanspaces.com/asencis/datasets/records/files/CHANDRA.2.0.source.tsv
- Raising ValidationError from django model's save method?
- Is npm in Node like virtualenv in Django?
- Can't connect to server running inside docker container (Docker for mac)
- Deploying existing Django app on Heroku