9

I have created a custom storage backend, the file is called storages.py and is placed in an app called core:

from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class S3StaticBucket(S3BotoStorage):
    def __init__(self, *args, **kwargs):
        kwargs['bucket_name'] = getattr(settings, 'static.mysite.com')
        super(S3BotoStorage, self).__init__(*args, **kwargs)

In settings.py, I have the follwing:

STATICFILES_STORAGE = 'core.storages.S3StaticBucket'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

When I try to do python manage.py collectstatic it shows the following error:

django.core.exceptions.ImproperlyConfigured: Error importing storage module core.storages: "No module named backends.s3boto"

And when I run python manage.py shell and try to import the same:

>>> 
>>> from django.conf import settings
>>> from storages.backends.s3boto import S3BotoStorage
>>> 

Any idea what I'm doing wrong?

Aziz Alfoudari
  • 5,193
  • 7
  • 37
  • 53
  • Are you able to import a `core.storages.S3StaticBucket` in shell as well? Maybe you missed an `__init__.py` file there. – Wojciech Żółtak Feb 24 '12 at 19:09
  • Just tried doing so, I got `ImportError: No module named backends.s3boto`. I do have an empty `__init__.py` in the app `core`. – Aziz Alfoudari Feb 24 '12 at 20:50
  • Hm. Try to comment a `from storages.backends.s3boto import S3BotoStorage` line in storages.py, and write instead a `import storages` and then in a following line `print storages.__file__`. Then import a `core.storages.S3StaticBucket` in shell. Then manually import `storages` in shell and print `storages.__file__`. If the paths differ - you have your answer. – Wojciech Żółtak Feb 24 '12 at 21:12
  • They are indeed different paths! `storages` in `storages.py` is referring to itself (the compiled file): `/home/ubuntu/project/core/storages.pyc` while the second `storages` is referring to the package itself: `/usr/local/lib/python2.7/dist-packages/storages/__init__.pyc`. So it looks like `storages` that is being imported in `storages.py` is considering itself as the default storage instead of the defined one in `settings.py`, which I don't understand. Any idea why is this happening? – Aziz Alfoudari Feb 24 '12 at 21:33
  • I've added a possible solution in an Answer below. – Wojciech Żółtak Feb 24 '12 at 21:38

4 Answers4

8

There is a namespace conflict; the storage absolute name clashes with a storage local name. It may be unintuitive, but you can import from module in itself:

// file my_module/clash.py
import clash
print clash.__file__

Now we run python shell in a dir containing a my_module:

$ python
>>> import my_module.clash
my_module.clash.py

In short, your module tries to import a backend from itself.

You need an absolute import - Trying to import module with the same name as a built-in module causes an import error.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
5

I had this same issue, but for me it turns out that despite django-storages being installed, boto was not. A simple pip install boto fixed the error in my scenario.

Parker
  • 8,539
  • 10
  • 69
  • 98
4

I had another type of issue that can help others, I used to have another file named storages.py but I deleted that file days ago, and still getting the Exception... the thing is I didn't had deleted the file storages.pyc !

dulaccc
  • 1,148
  • 11
  • 12
0

Typo error. Change:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

TO:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3Boto3Storage'

Roby96
  • 3
  • 1