我有几个使用django-storage与Amazon S3的课程
class Cache(models.Model):
identifier = models.TextField(blank=True, null=True)
cache_file = models.FileField(upload_to="cache")
现在我需要获取缓存文件位置的URL。
cache = cache.objects.get(identifier=identifier)
cache_file = cache.cache_file
缓存文件是FieldFile
对象,其中包含storage
个对象。
在数据库中我只看到我之前保存的值cache/file.json
。
在这种情况下,我不需要获取文件,而是文件所在的完整URL 我怎么能得到这个?
答案 0 :(得分:3)
我知道这个问题已经得到解答,但万一有人在偶然发现这个问题时正在寻找我需要的东西......
我发现大型查询从模型实例(report.file.url
)中拉出url会导致在我需要提取大量记录的情况下出现糟糕的性能,因为Django会在每个记录执行数据库查询时以这种方式访问模型字段。下面是一个替代方法的示例实现,您可以预先执行整个查询,如果需要,仍然可以获取URL。
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
]
答案 1 :(得分:2)
该文件应位于:
cache = cache.objects.get(identifier=identifier)
cache_file = cache.cache_file
cache_file_url = cache.cache_file.url
调用此方法获取完整的S3 URL,但您应该设置django存储来获取此URL。
答案 2 :(得分:0)
尽管我们现在有2个不错的答案,但值得探讨一下media_storage.url()
通话背后的内容:
***假设我们在django-storages
中安装了settings.py
,并具有正确的设置,例如:
# 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)
这可确保无论使用哪种存储方法,我们都将始终检索绝对URI位置,例如"https://<AWS_S3_REGION_NAME>.<AWS_S3_ENDPOINT_URL>/<AWS_STORAGE_BUCKET_NAME>/<UPLOADS_TO>/<FILENAME>"
。
例如https://nyc3.digitaloceanspaces.com/asencis/datasets/records/files/CHANDRA.2.0.source.tsv