I have a Django web app where users upload images and others view them. I have a custom storage class in this app to upload image files to Azure Cloud Storage. Currently images are being uploaded successfully, but their urls are not being set. Thus, the following code in my template yields a broken image:
{% if entry.image_file %}
<img src="{{ entry.image_file.url }}"></img><br>
{% endif %}
Can you point out what my custom storage class is missing? Here's how it appears in my models.py currently:
from django.db import models
import os
from django.conf import settings
from django.core.files.storage import Storage
from azure.storage.blob import BlobService
accountName = 'accname'
accountKey = 'acckey'
class OverwriteStorage(Storage):
container = 'containername'
account_name = accountName
account_key = accountKey
def __init__(self, account_name=None, account_key=None, container=None):
if account_name is not None:
self.account_name = account_name
if account_key is not None:
self.account_key = account_key
if container is not None:
self.container = container
def __getstate__(self):
return dict(
account_name=self.account_name,
account_key=self.account_key,
container=self.container
)
def _save(self,name,content):
blob_service = BlobService(account_name=accountName, account_key=accountKey)
import mimetypes
content.open()
content_type = None
if hasattr(content.file, 'content_type'):
content_type = content.file.content_type
else:
content_type = mimetypes.guess_type(name)[0]
print content_type
content_str = content.read()
blob_service.put_blob(
'containername',
name,
content_str,
x_ms_blob_type='BlockBlob',
x_ms_blob_content_type=content_type
)
content.close()
return name
def get_available_name(self,name):
return name
def _get_service(self):
if not hasattr(self, '_blob_service'):
self._blob_service = BlobService(
account_name=self.account_name,
account_key=self.account_key,
protocol='http'
)
return self._blob_service
def _open(self, name, mode='rb'):
from django.core.files.base import ContentFile
contents = self._get_service().get_blob(self.container, name)
return ContentFile(contents)
def _get_properties(self, name):
return self._get_service().get_blob_properties(
self.container,
name
)
def _get_container_url(self):
if not hasattr(self, '_container_url'):
base_url = '{protocol}://{host}/{container}'
if self.cdn_host:
base_url = self.cdn_host
self._container_url = base_url.format({
'protocol': 'http',
'host': self._get_service()._get_host(),
'container': self.container,
})
return self._container_url
def url(self, name):
url = '%s/%s' % (self._get_container_url(), name)
return url
class Entry(models.Model):
description = models.TextField(validators=[MaxLengthValidator(500)])
submitted_on = models.DateTimeField(auto_now_add=True)
image_file = models.ImageField(upload_to=upload_to_location, storage=OverwriteStorage(), null=True, blank=True )
The example I'm following is here. I have looked at django documentation for custom file storage, and if you scroll through the code I've pasted above, I've defined a url(self, name):
method. Yet this doesn't get called (I've tested it with a print
statement). Please advise!