【问题标题】:ImportError: cannot import name 'safe_join'ImportError:无法导入名称“safe_join”
【发布时间】:2019-06-29 11:57:07
【问题描述】:

我想通过 s3 将我的静态文件上传到 AWS CloudFront。 我有这个错误:ImportError: cannot import name 'safe_join' 运行时python manage.py collectstatic

我正在使用 Python 3.6 和 Django 2x。 django-storage-redux 已安装,boto3botocore 也已安装。

这是我的settings.py

import os
from django.utils.translation import ugettext_lazy as _
import boto3

...


# AWS CloudFront
AWS_S3_REGION_NAME = 'us-east-2'  # e.g. us-east-2
AWS_ACCESS_KEY_ID = '****'
AWS_SECRET_ACCESS_KEY = '***'
AWS_S3_HOST = 's3-us-east-2.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=1209600, no-transform'
}

# static
BUCKET_STATIC_NAME = '***'
CLOUDFRONT_STATIC_DOMAIN = '***'

# media
BUCKET_MEDIA_NAME = '***'
CLOUDFRONT_MEDIA_DOMAIN = '***'

# storage
DEFAULT_FILE_STORAGE = 'elef.custom_storage.CachedStaticS3BotoStorage'
STATICFILES_STORAGE = 'elef.custom_storage.MediaS3BotoStorage'

MEDIA_URL = 'https://%s/' % CLOUDFRONT_MEDIA_DOMAIN

...

这是我的custom_storage.py

from storages.backends.s3boto3 import S3Boto3Storage
import boto3

from django.conf import settings
from django.contrib.staticfiles.storage import CachedFilesMixin


class CachedStaticS3BotoStorage(CachedFilesMixin, S3Boto3Storage):
    """
    S3BotoStorage backend which also saves a hashed copies of the files it saves.
    """
    bucket_name = settings.BUCKET_STATIC_NAME
    custom_domain = settings.CLOUDFRONT_STATIC_DOMAIN


class MediaS3BotoStorage(S3Boto3Storage):
    """
    S3BotoStorage backend for media files.
    """
    bucket_name = settings.BUCKET_MEDIA_NAME
    custom_domain = settings.CLOUDFRONT_MEDIA_DOMAIN

我也可以给你完整的回溯:

/Users/justine_dev/zapelef/lib/python3.6/site-packages/storages/__init__.py:9: UserWarning: This library has been designated as the official successor of django-storages and releases under that namespace. Please update your requirements files to point to django-storages.
  warnings.warn('This library has been designated as the official successor of django-storages and '
Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/core/management/base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 162, in handle
    if self.is_local_storage() and self.storage.location:
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 216, in is_local_storage
    return isinstance(self.storage, FileSystemStorage)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/utils/functional.py", line 213, in inner
    self._setup()
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 491, in _setup
    self._wrapped = get_storage_class(settings.STATICFILES_STORAGE)()
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/core/files/storage.py", line 356, in get_storage_class
    return import_string(import_path or settings.DEFAULT_FILE_STORAGE)
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/Users/justine_dev/zapelef/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "/Users/justine_dev/Desktop/elefmarket/elef/custom_storage.py", line 1, in <module>
    from storages.backends.s3boto3 import S3Boto3Storage
  File "/Users/justine_dev/zapelef/lib/python3.6/site-packages/storages/backends/s3boto3.py", line 18, in <module>
    from storages.utils import safe_join, setting
ImportError: cannot import name 'safe_join'

我可以在回溯中看到我需要“更新我的需求文件以指向 django-storages”。不知道什么意思,还装了django-storages

【问题讨论】:

    标签: python django amazon-s3 boto3 django-storage


    【解决方案1】:

    您不想使用django-storages-redux,警告是正确的告诉您应该用django-storages 替换它。您的错误是由于同时安装了django-storagesdjango-storages-redux 而引起的。您应该删除 -redux 软件包,并通过单独重新安装 django-storages 来修复您的设置。

    发出警告是因为您安装了已弃用的 django-storages-redux project 的 1.3.3 版;这是only release with that warning。 1.3.3版本比较老了,2017年发布的。

    你需要卸载那个项目,然后重新安装django-storages:

    pip uninstall django-storages-redux
    pip install --force-reinstall django-storages
    

    确保django-storages-redux 未列在您的 requirements.txt 文件中或作为任何地方的依赖项。

    django-storages-reduxdjango-storages 项目写入同一个包,它们发生冲突,创建了一个损坏的包。 storage.utils 模块是the version from django-storages-redux,而storage.backends.s3boto3 模块是new in version 1.5.0 of `django-storage

    【讨论】:

    • 谢谢!现在我有另一个错误:botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied。我想这是一个aws config问题,如果你也有这个答案,那就太好了哈哈!否则我会在另一个问题中问这个(我所有的存储桶都有正确的权限,所以我不明白)
    • @justinedupuis:是的,那将是一个新问题。抱歉,我最近没有任何 boto 配置经验,我不知道你为什么会收到这个错误。
    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 2014-10-10
    • 2014-09-20
    • 2014-08-28
    • 2014-06-10
    • 2016-05-16
    • 2019-05-25
    • 2017-04-22
    相关资源
    最近更新 更多