Django将blob格式的azure-storage作为可下载文件返回

时间:2017-10-11 07:27:39

标签: django python-2.7 azure azure-storage-blobs

我是azure-storage和django的新手 我的开发环境软件配置是as-django 1.10,python 2.7.6,azure-storage-blob 0.37。我使用django应用程序作为webservice api,使用angular-2和HTML构建前端

我使用azure blob存储来存储任何类型的文件。

azure blob我保存文件的容器只有私有访问权限。我能够成功上传文件。

问题是在下载文件时 - 我想要实现的是 -

  1. 当有人点击页面请求上的超链接时,将转到带有blob名称的django视图。然后我可以使用容器名称和blob名称获取blob

    block_blob_service._get_blob(容器,blob_name)

  2. 我想在django响应中将该blob作为可下载文件返回。

  3. 你能否建议我能做到解决方案或更好的方法。

    提前致谢。

2 个答案:

答案 0 :(得分:3)

我建议你在Django中使用Azure Storage System

请按照此tutorial在项目中配置您的azure存储帐户。

# Replace <...> appropriately with your information

# AzureStorage Settings
AZURE_STORAGE_ACCOUNT = "<account_name>"
AZURE_STORAGE_KEY = "<account_key>"
AZURE_STORAGE_CONTAINER = "<default_storage_container>" # statics will use this container

# Static Settings
STATICFILES_STORAGE = "<my_project>.storage.AzureStorage"
STATIC_URL = "http://<storage account>.blob.core.windows.net/<default_storage_container>/"

# Media Settings
MEDIA_URL = 'http://storage.pepperdeck.com/<media_container>/'

您可以获得更多详细信息herehere

更新答案: 实际上,我昨天提供的Django-Azure-Storage基本上是azure storage SDK的适配器调用。您在回复中提到的media container实际上并不需要配置,因为您只需要参考azure存储。

根据您的需要,只使用Azure存储Python SDK。

请按照以下步骤操作。

第1步 :将要下载的blob名称绑定到hyperlink,并将blob name作为参数传递给用户点击时的后端。

Step2 :获取blob网址。

def GetBlobUrl():
    blobService = BlockBlobService(account_name=accountName, account_key=accountKey)
    sas_token = blobService.generate_container_shared_access_signature(containerName,ContainerPermissions.READ, datetime.utcnow() + timedelta(hours=1))
    # print url
    return 'https://' + <your_account_name> + '.blob.core.windows.net/' + <your_container_name> + '/<your_blob_name>?' + sas_token

第3步 :通过StreamingHttpResponse在浏览器中下载文件。

import requests
from django.http import StreamingHttpResponse

def stream_file(request, *args, **kwargs):
    file_url = "<blob url you get in the Previous step >"

    r = requests.get(file_url, stream=True)

    resp = StreamingHttpResponse(streaming_content=r)
    resp['Content-Disposition'] = 'attachment; filename="<your blob name>"'

您还可以参考以下主题:

1。Stream file from remote url to Django view response

2。how to stream file to client in django

希望它对你有所帮助。

答案 1 :(得分:0)

我可以在@Jay Gong 的回答中加上我的几分钱。

第一个答案

这是 azure-storage-blob v12 的解决方案。

azure-storage-blob==12.8.1
import requests

from django.http import StreamingHttpResponse

from app_module.settings import AZURE_ACCOUNT_KEY # blob storage access key
from app_module.settings import AZURE_ACCOUNT_NAME # blob storage name
from app_module.settings import AZURE_CONTAINER # name of container
from app_module.settings import AZURE_ENDPOINT_SUFFIX # "core.windows.net"


def get_blob_url(file_path):
    sas_token = generate_account_sas(
        account_name=AZURE_ACCOUNT_NAME,
        account_key=AZURE_ACCOUNT_KEY,
        resource_types=ResourceTypes(service=True, container=True, object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )

    return f'https://{AZURE_ACCOUNT_NAME}.blob.{AZURE_ENDPOINT_SUFFIX}/{AZURE_CONTAINER}/{file_path}?{sas_token}'


def download(request):
    file_name = 'example.png'
    file_location_in_blob = '/path/to/file/inside/blob/storage/' + file_name

    url = get_blob_url(file_location_in_blob)

    request = requests.get(url, stream=True)
    response = StreamingHttpResponse(streaming_content=request)

    response['Content-Disposition'] = f'attachment; filename={file_name}'

    return response

第二个答案

这是 azure-storage-blob v2 的解决方案。它更优雅,因为您不必构建流响应。

azure-storage-blob==2.1.0 
from django.http import HttpResponse

def download(request):
    object = Model.objects.last()
    
    # file is FileField or its deriveritives ImageField
    response = HttpResponse(object.file) 
    response['Content-Disposition'] = f'attachment; filename={file_name}'

    return response