2015-12-16 1 views
0

У меня есть веб-приложение Django, где пользователи загружают изображения, а другие просматривают их. У меня есть специальный класс хранения в этом приложении для загрузки файлов изображений в Azure Cloud Storage. В настоящее время изображения загружаются успешно, , но их URL-адреса не установлены. Таким образом, следующий код в шаблоне дает broken image:Настройка URL-адреса атрибута модели Django Imagefield через пользовательское хранилище, написанное для Azure Cloud Storage

{% if entry.image_file %} 
<img src="{{ entry.image_file.url }}"></img><br> 
{% endif %} 

Можете ли вы указать на то, что отсутствует мой собственный класс для хранения? Вот как это выглядит в моем models.py в настоящее время:

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) 

Пример я следую является here. Я просмотрел django documentation для хранения пользовательских файлов, и если вы прокрутите код, который был вставлен выше, я определил метод url(self, name):. Но это не вызвано (я протестировал его с помощью инструкции print). Пожалуйста, порекомендуйте!

ответ

1

Blobs in Azure Blob Storage имеют свои уникальные URL-адреса для доступа. URL-адрес находится в формате: http://<your_storage_name>.blob.core.windows.net/<container_name>/<blob_name>, вы можете получить к нему доступ в браузере, если вы установили доступ к blob для публики.

К вашему вопросу, если он не чувствителен к вашим изображениям в хранилище Blob, вы можете просто установить разрешение доступа на public blob, чтобы разрешить доступ к общедоступному доступу к блокам в контейнере, но не к свойствам и метаданным контейнера.

Войти в Azure mange portal, выберите вкладку хранения в левой навигационной панели выберите имя хранилища в списке к шагу в вашем хранилище управление страницей, нажмите КОНТЕЙНЕРАМ вкладку, выберите конкретное имя контейнера, нажмите EDIT кнопку в нижней части , изменить разрешение доступа и нажмите кнопку OK, чтобы сохранить конфигурацию:

enter image description here

нажмите на имя контейнера мы можем шагнуть в списке сгустков в этом контейнере. Мы можем скопировать URL-адрес элемента, посетить в браузере, чтобы проверить.

И в моем понимании, если вы хотите показать изображения после загрузки в хранилище Azure, нам просто нужно внести несколько изменений в исходный код.

В пользовательском классе хранения предположим, что функция url() должна вернуть правильный URL. В моем тесте, я сразу возвращает строку URL для быстрой проверки:

def geturl(self,name): 
    return '%s/%s/%s' % ('http://garyteststorage.blob.core.windows.net','mycontainer', name) 

И мы можем изменить возвращение функции _save() к URL класса изображений вместо name:

url = self.geturl(name) 
return url 
#return name 

В models.py:

def upload_path(instance, filename): 
    return 'uploads-from-custom-storage-{}'.format(filename) 

class Photo(models.Model): 
    #description = models.TextField(validators=[MaxLengthValidator(500)]) 
    #submitted_on = models.DateTimeField(auto_now_add=True) 
    image_file = models.ImageField(upload_to=upload_path, storage=OverwriteStorage(), null=True, blank=True) 

Как и прежде, она сохранит Нам изображения e в базе данных, и после изменения он сохранит полный URL-адрес blob в базе данных.

код фрагмента вид сверху.py:

if form.is_valid(): 
    newImage = Photo(image_file = request.FILES['image_file']) 
    newImage.save() 
    imageurl = newImage.image_file 
    html = "<img src=%s></img><br>" %imageurl 
    # Redirect to the document list after POST 
    return HttpResponse(html) 
Смежные вопросы