2015-12-16 17 views
0

我有一个Django网络应用程序,用户上传图像和其他人查看它们。我在这个应用程序中有一个自定义存储类,用于将图像文件上传到Azure云存储。目前图片上传成功,,但他们的网址没有设置。因此,在我的模板下面的代码产生一个broken image通过为Azure云存储编写的自定义存储设置Django Imagefield模型属性的url

{% 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

Azure Blob存储中的Blob具有自己独特的访问URL。 URL格式为:http://<your_storage_name>.blob.core.windows.net/<container_name>/<blob_name>,如果您将blob的访问权限设置为public,则可以直接在浏览器中访问它。

您的问题,如果是在Blob存储你的图像不敏感,你可以简单地设置访问权限public blob,使容器公共读取权限的斑点,但不是容器的属性和元数据。

登录在Azure mange portal,单击存储选项卡左侧导航栏中,单击列表中的存储名称步骤在存储管理页面,点击集装箱选项卡中,选择特定的容器名称,单击底部的编辑按钮,改变访问权限,然后单击确定按钮保存配置:

enter image description here

单击容器名称我们就可以在这个容器中的blob的列表步骤。我们可以复制项目的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) 

和以前一样,它会保存图像nam e在数据库中,并且在修改后,它将在数据库中保存blob的完整url。

代码片段在视图中。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)