Configure Django Imagefield model attribute url through user store written for Azure Cloud Storage

I have a Django web application where users upload images while others view them. I have a special storage class in this application for uploading image files to Azure Cloud Storage. Images are currently loading successfully , but their URLs are not set. Thus, the following code in my template gives a broken image :

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

Can you indicate that my custom storage class is missing? Here's what it looks like in my models.py now:

 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 ) 

In the following example, I am here . I looked at the django documentation for a custom file vault, and if you scroll through the code pasted above, I defined the url(self, name): method. But this is not caused (I tested it with the print statement). Please advise!

0
source share
1 answer

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

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

Log in to the Azure mange portal , click the vault tab in the left navigator, click the name of your vault in the list to go to the vault management page, click the CONTAINERS tab, select a specific container name, click the EDIT button at the bottom, change the access permission and click "OK" to save the configuration:

enter image description here

Click the name of the container that we can put in the list of blocks in this container. We can copy the URL of the item, visit in the browser to check.

And for my understanding, if you want to display images after uploading to Azure storage, we just need to make a few changes to the source code.

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

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

And we can change the return of the _save() function to the image class URL instead of name :

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

In 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 ) 

As before, it will save the image name in the database and after modifying it will save the full blob URL in the database.

code snippet In 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) 
+1
source

Source: https://habr.com/ru/post/1238132/


All Articles