2017-06-11 4 views
0

Ich wurde beauftragt, eine Admin-Ansicht zu erstellen, so dass ein Benutzer eine Bilddatei eingeben könnte, die jedoch als Base64-String als Modellfeld statt existiert in einem statischen Verzeichnis auf unserem Server.Django: habe Admin Bilddatei aufnehmen, aber als Base64 String speichern

Ich bin unklar, wie genau dieser Prozess gemacht würde, sollte ich die POST-Anfrage von der Admin-Ansicht abfangen und vorverarbeiten, um im Feld gespeichert zu werden? Sollte ich die Speichermethode des Basisformulars überschreiben? Ich bin etwas verwirrt wegen der verschiedenen Methoden, da ich neu in Django bin und kein Arbeitsergebnis erzielen konnte.

Hier ist mein Setup:

models.py

from django.db import models 

class Product(models.Model): 
    organization = models.ForeignKey(Organization) 
    name = models.CharField(max_length=50) 
    logo = models.TextField() 

admin.py

from django.contrib import admin 
from .models import Product 

class ProductAdmin(admin.ModelAdmin): 
    exclude = ('logo',) 

admin.site.register(Product, ProductAdmin) 

misc.py

#how i'd process an image? 
from PIL import Image 
from base64 import b64encode 

def image_to_b64(image_file): 
    imgdata = Image(image_file) 
    encoded = b64encode(open(imgdata, 'rb')) 
    return encoded 
+0

, wenn Sie eine logo_file hinzufügen annehmen können (Imagefield) zu Ihnen Produkt, wird es durch Überschreibung Speichermethode Probe sein, in denen Sie in Admin-Modell oder Form. – Ykh

+0

@Ykh Ich versuche, das Bild überhaupt nicht auf dem Server gespeichert zu haben; Können Sie ein funktionierendes Beispiel dafür liefern, wie das funktionieren würde? – mburke05

Antwort

1
from django.db import models 

class Product(models.Model): 
    organization = models.ForeignKey(Organization) 
    name = models.CharField(max_length=50) 
    logo = models.TextField() 
    logo_image = models.ImageFiled(null=True, blank=True, upload_to='logo') 


def image_to_b64(image_file): 
    import base64 
    with open(image_file.path, "rb") as f: 
     encoded_string = base64.b64encode(f.read()) 
     return encoded_string 

from django.dispatch import receiver 
from django.db.models.signals import post_save, m2m_changed 


@receiver(post_save, sender=Product) 
def create_base64_str(sender, instance=None, created=False, **kwargs): 
    if created: 
     instance.logo = image_to_b64(instance.logo_image) 
     instance.logo_image.delete() 
     instance.save() 
+0

danke dafür; Die zweite Reihe von Importen und die 'create_base64_str'-Funktion sollten in der models-Datei enthalten sein. Kannst du kurz erklären, wie das funktioniert? – mburke05

+1

'create_base64_str' muss nicht in model.py leben, wenn Sie diese Funktion in signals.py entfernen möchten, müssen Sie '.signals import create_base64_str' zu Ihrer model.py oder view.py hinzufügen, auch wenn Sie nicht ' t brauchen es. Diese Funktion wird aufgerufen, nachdem Sie Produkt Instanz von Admin oder anderen Schnittstelle erstellen, wenn eine neue Produktinstanz erstellt wird, ich logo_image zu base64 konvertieren und base64 zu Logo (TextField) speichern, dann löschen Sie die nutzlose logo_image.More info über Signale siehe https://docs.djangoproject.com/en/1.11/topics/signals/ – Ykh

+0

dies funktionierte PERFEKT. Vielen Dank dafür und dafür, dass du meine Augen für die Welt der Signale öffnest! Ich habe bemerkt, dass dies aus irgendeinem Grund nicht funktionierte, wenn ich ein existierendes Objekt bearbeite, weil post_save nur post_save von neuen Objekten handhabt? oder ist das ein Fehler? Nochmals vielen Dank für die Hilfe. – mburke05