jschneier / django-storages

https://django-storages.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
2.77k stars 866 forks source link

gcloud raises NotFound exception on self.storage.url(self.name) #463

Closed sww314 closed 6 years ago

sww314 commented 6 years ago

I am serializing an ImageFileField with Django RestFramework. If the file does not exist it raises NotFound().

I am not sure how the other network storage layers work, but this is not how the file storage in Django core works it will simply return a URL.

I suggest the code be changed to return the URL without checking to see if the blob exists.

zisk0 commented 6 years ago

Hi!

We have been hitting the same problem. When URL is built, _get_blob() is called and raises a NotFound exception if file does not exists. As a workaround, we wrote a CustomImageField that builds the URL in case the file doesn't exist, but _get_blob() is always executed. I also realized it introduces some overhead when listing objects with images. Is it possible that the reason is the execution of _get_blob() connecting to GCS?

sww314 commented 6 years ago

@zisk0 Yes. get_blob connects to GCS. I do not think it should unless you need the file retrieved for writes, reads, etc. Currently, it will make a call to verify the bucket exists as well (making it slower).

zisk0 commented 6 years ago

AFAIK it is to obtain the public_url of the blob. We were working to control this URL using:

 def url(self, name):
    # Preserve the trailing slash after normalizing the path.
    name = self._normalize_name(clean_name(name))
    if self.base_url:
        return self.base_url + name
    else:
        blob = self._get_blob(self._encode_name(name))
        return blob.public_url

Where self.base_url is a setting:

class GoogleCloudStorage(Storage): // ... base_url = setting('GS_CDN_BASE_URL', None)

This is also a workaround for #385. Now load speed has been improved.

jschneier commented 6 years ago

All of this discussion is now ongoing in #491.