通过对Azure的云存储编写自定义存储设置的Django ImageField的模型属性的网址 [英] Setting url of Django Imagefield model attribute via custom storage written for Azure Cloud Storage

查看:384
本文介绍了通过对Azure的云存储编写自定义存储设置的Django ImageField的模型属性的网址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django的web应用程序,用户上传图片和其他人查看。我在此应用程序的自定义存储类图像文件上传到Azure的云存储。目前,图像被成功上传,但他们的URL不被设置。因此,在我的模板下面code产生一个​​的破碎的形象

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

您可以指出什么我的自定义存储类不见了?下面是它的出现在我的 models.py 目前

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 )

我在下面的示例是这里。我看过<一个href=\"https://docs.djangoproject.com/en/1.9/ref/files/storage/#django.core.files.storage.Storage.url\"相对=nofollow>自定义文件存储Django文档,如果​​你通过code我上面粘贴的滚动,我已经定义了一个 URL(个体经营,名称) 方法。然而,这不会被调用(我用打印语句测试过)。请指教!

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!

推荐答案

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

The Blobs in Azure Blob Storage have their own unique urls for accessing. The URL is in the format: http://<your_storage_name>.blob.core.windows.net/<container_name>/<blob_name>, you can directly access it in browser, if you set the access permission of blob to public.

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

To your issue, if it is not sensitive to your images in Blob Storage, you can simply set access permission to public blob to allow public read access to the blobs in the container, but not the container properties and metadata.

登录 Azure的奶源门户,点击存储卡在左侧导航栏中,在列表中单击存储名称步在存储管理页面,点击集装箱标签,选择特定的容器名称,请点击编辑在底部按钮,更改访问权限,然后单击确定按钮保存配置

Login in Azure mange portal, click storage tab in left nav, click your storage name in the list to step in your storage manage page, click CONTAINERS tab, select the specific container name, click the EDIT button in bottom, change the access permission and click OK button to save the configuration:

在这里输入的形象描述

点击容器名称,我们可以在这个容器中的blob的列表步骤。我们可以复制项目的URL,请访问浏览器有一个检查。

Click the container name we can step in the list of blobs in this container. We can copy the URL of an item, visit in browser to have a check.

和按我的理解,如果你想上传到Azure存储后,显示的图像,我们只需要在原来的code一些修改。

And per my understanding, if you want to show the images after uploading to Azure storage, we just need a few modification on the original code.

在自定义存储类,采用的功能网​​址()应返回正确的URL。在我的测试,我直接返回的URL字符串进行快速测试:

In the custom storage class, assume the function url() should return the correct the URL. In my test, I directly return the URL string for a quick test:

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

和我们可以修改函数的返回 _save()网​​址图像类,而不是名称

And we can modify the return of function _save() to the URL of the image class instead of 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 )

和以前一样,它会在数据库中保存图像名称,修改后,这将节省blob的完整URL数据库。

As before, it will save the image name in database, and after modification, it will save the full url of blob in database.

code段在view.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)

这篇关于通过对Azure的云存储编写自定义存储设置的Django ImageField的模型属性的网址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆