1. David Larlet
  2. django-storages

Issues

Issue #147 resolved

SFTPStorage.url returns a sftp:// URL

Ewoud Kohl van Wijngaarden
created an issue

From django.core.files.storage.Storage:

def url(self, name):
    """
    Returns an absolute URL where the file's contents can be accessed
    directly by a Web browser.
    """
    raise NotImplementedError()

However, the SFTPStorage implementation returns sftp://host/path which isn't directly accessible by any client. At least not in my use case.

In my use case I have a separate webserver and I want to use SFTP to upload files there. So in essence replace MEDIA_ROOT with SFTP_STORAGE_ROOT, but MEDIA_URL should still work.

Comments (6)

  1. Dan Abel

    you can easily fix this by copying the url() from ftp.py to sftpstorage.py and setting self._base_url as settings.MEDIA_URL in init()

    ...
    import urlparse
    ...
    class SFTPStorage(Storage):
        def __init__(self):
            ...
            self._base_url = settings.MEDIA_URL
            ...
        ...
        def url(self, name):
            if self._base_url is None:
                raise ValueError("This file is not accessible via a URL.")
            return urlparse.urljoin(self._base_url, name).replace('\\', '/')
    
  2. Ewoud Kohl van Wijngaarden reporter

    Sorry for the very late response, but I only now got around to updating this part in our code base. I can confirm I no longer need a custom storage to override url, but SFTPStorageFile has no attribute name so I still apply the following workaround:

    if hasattr(file, 'name'):
        filename = file.name
    else:  # For SFTPStorageFile
        filename = file._name
    
    url = file_storage.url(filename)
    
  3. Log in to comment