N
N
Nodir Malikov2022-03-06 21:44:12
Django
Nodir Malikov, 2022-03-06 21:44:12

How to hook up S3 file storage (Selectel) on django-filebrowser?

I installed django-filebrowser-no-grappelli because the dependency on the django-grappelli standard library conflicts with django-tinymce.

On my project, when starting the django server on DEBUG=False, the server automatically switches to storage from Selectel. When debugging, everything works fine, there are no errors, but after disabling it, the filebrowser does not want to work with storage, it gives an error 500.

a piece of settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'news/static'),
                    os.path.join(BASE_DIR, 'konkurs/static')]

if config.app.debug:
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    MEDIA_URL = '/media/'
else:
    if config.app.whitenoise:
        STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
    else:
        STATICFILES_STORAGE = 'django_selectel_storage.storage.SelectelStorage'

    DEFAULT_FILE_STORAGE = 'django_selectel_storage.storage.SelectelStorage'

    if 'filebrowser' in INSTALLED_APPS:
        fb_sel_st = 'news.services.custom_storage_for_filebrowser.SelectelStorageForFileBrowser' # здесь я после первой ошибки написал класс который наследует от S3BotoStorageMixin и SelectelStorage
        STATICFILES_STORAGE = fb_sel_st
        DEFAULT_FILE_STORAGE = fb_sel_st

    SELECTEL_STORAGES = {
        'default': {
            'USERNAME': config.selectel.user,
            'PASSWORD': config.selectel.password,
            'CONTAINER': config.selectel.container,
            'CUSTOM_DOMAIN': config.selectel.custom_domain if config.selectel.custom_domain else False,
        },
    }



The first time I got an error:
'SelectelStorage' object has no attribute 'isdir'

Then I wrote a class according to the recommendations on github:
from django_selectel_storage.storage import SelectelStorage
from filebrowser_safe.storage import S3BotoStorageMixin, clean_name

class SelectelStorageForFileBrowser(S3BotoStorageMixin, SelectelStorage):
    pass


For some, this code solved the problem, but I got error after error:
'SelectelStorageForFileBrowser' object has no attribute '_normalize_name'

'SelectelStorageForFileBrowser' object has no attribute '_clean_name'

'SelectelStorageForFileBrowser' object has no attribute 'bucket'


So my class ended up looking like this...

from django_selectel_storage.storage import SelectelStorage
from filebrowser_safe.storage import S3BotoStorageMixin, clean_name


class SelectelStorageForFileBrowser(S3BotoStorageMixin, SelectelStorage):
    def _clean_name(self, name):
        """
        Cleans the name so that Windows style paths work
        """
        return clean_name(name)

    def _normalize_name(self, name):
        pass

    def isdir(self, name):
        # That's some inefficient implementation...
        # If there are some files having 'name' as their prefix, then
        # the name is considered to be a directory
        if not name:  # Empty name is a directory
            return True

        if self.isfile(name):
            return False

        name = self._normalize_name(self._clean_name(name))
        dirlist = self.bucket.list(self._encode_name(name))

        # Check whether the iterator is empty
        for item in dirlist:
            return True
        return False



I got tired of digging further than this error.
'SelectelStorageForFileBrowser' object has no attribute 'bucket'


In the official repository, I understand that django-filebrowser does not support S3 so far.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question