Einstellen der URL von Django Imagefield Modellattribut über benutzerdefinierte Speicherung für Azure Cloud Storage geschrieben

Ich habe eine Django Web-App, wo Benutzer Bilder hochladen und andere sehen sie. Ich habe eine benutzerdefinierte Speicherklasse in dieser App zum Hochladen von Bilddateien auf Azure Cloud Storage. Derzeit werden die Bilder erfolgreich hochgeladen, aber ihre URLs werden nicht gesetzt. So ergibt der folgende Code in meiner Vorlage ein gebrochenes Bild :

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

Können Sie darauf hinweisen, was meine benutzerdefinierte Speicherklasse fehlt? Hier ist, wie es in meinem models.py erscheint derzeit:

 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 ) 

Das Beispiel, das ich folge, ist hier . Ich habe bei django Dokumentation für benutzerdefinierte Datei gespeichert, und wenn Sie durch den Code scrollen, den ich oben eingefügt habe, habe ich eine url(self, name): Methode definiert. Doch das wird nicht angerufen (ich habe es mit einer print Anweisung getestet). Bitte beraten!

One Solution collect form web for “Einstellen der URL von Django Imagefield Modellattribut über benutzerdefinierte Speicherung für Azure Cloud Storage geschrieben”

Die Blobs in Azure Blob Storage haben ihre eigenen einzigartigen URLs für den Zugriff. Die URL ist im Format: http://<your_storage_name>.blob.core.windows.net/<container_name>/<blob_name> , kannst du direkt im Browser darauf zugreifen, wenn du die Zugriffsberechtigung von Blob auf die Öffentlichkeit http://<your_storage_name>.blob.core.windows.net/<container_name>/<blob_name> .

Zu Ihrem Problem, wenn es nicht empfindlich auf Ihre Bilder in Blob Storage ist, können Sie einfach Zugriffsberechtigung für public blob , um öffentlichen Lesezugriff auf die Blobs im Container zu ermöglichen, aber nicht die Container-Eigenschaften und Metadaten.

Melden Sie sich im Azure Mange Portal an , klicken Sie auf die Registerkarte Speicher in der linken Navigation, klicken Sie auf Ihren Speichernamen in der Liste, um in Ihre Speicherverwaltungsseite zu gelangen, klicken Sie auf die Registerkarte CONTAINERS , wählen Sie den spezifischen Containernamen aus, klicken Sie auf die Schaltfläche EDIT , um die Zugriffsberechtigung zu ändern Klicken Sie auf OK, um die Konfiguration zu speichern:

Bildbeschreibung hier eingeben

Klicken Sie auf den Containernamen, den wir in die Liste der Blobs in diesem Container treten können. Wir können die URL eines Artikels kopieren, im Browser besuchen, um einen Scheck zu haben.

Und nach meinem Verständnis, wenn du die Bilder nach dem Hochladen auf Azure-Speicher zeigen willst, brauchen wir nur ein paar Änderungen am Originalcode.

In der benutzerdefinierten Speicherklasse, nehmen Sie die Funktion url() sollte die korrekte URL zurückgeben. In meinem Test gebe ich direkt die URL-String für einen schnellen Test zurück:

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

Und wir können die Rückkehr der Funktion _save() auf die URL der _save() anstelle des name ändern:

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

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

Wie vorher, wird es den Bildnamen in der Datenbank speichern, und nach der Änderung wird es die volle URL des Blob in der Datenbank speichern.

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) 
Python ist die beste Programmiersprache der Welt.