Wie zu verwenden Django ImageField, und warum Sie überhaupt nutzen?
Bis jetzt, ich habe der Speicherung meiner Bild-Dateinamen in CharField und speichern die aktuelle Datei direkt auf S3. Das war eine feine Lösung für meine eigene Nutzung. Ich möchte zu überdenken, mit einem ImageField, denn jetzt wird es anderen Benutzern und Datei-input-validation-angemessen wäre.
Ich habe ein paar Fragen, die nicht genau beantwortet nach dem Lesen die docs und der source-code für FileField (die, wie es scheint im wesentlichen ImageField minus die Kissen überprüfen und dimension Feld Update-Funktionalität).
1) Warum verwenden Sie ein ImageField überhaupt? Oder eher, warum verwenden Sie ein FileField? Sicher, es ist bequem für eine schnelle und einfache Formen und bequem für das einfügen in Django-templates. Aber gibt es auch erhebliche Gründe, wie zB. Es ist offenbar gesichert gegen exploits und schädliche uploads?
2) schreiben Sie in das Feld Datei? Wenn es richtig ist, dass die Datei gelesen werden kann instance.imagefield
(oder ist es instance.imagefield.file
?), wenn ich will, zu schreiben, kann ich einfach Folgendes machen?
@receiver(pre_save, sender=Image)
def pre_save_image(sender, instance, *args, **kwargs):
instance.imagefield = process_image(instance.imagefield)
3) Wie versuchen Sie, das speichern mit bestimmten Dateinamen und versuchen Sie es erneut mit einem neuen Dateinamen, wenn die, die zufällig generierte Dateiname bereits existiert? Zum Beispiel mit meinem code ich jetzt tun, wie kann es getan werden, mit ImageField? Ich möchte es auf der Modell-Ebene, weil wenn ich das Tue wiederholt versucht, an die view-Schicht dann die pre_save
Verarbeitung würde wieder laufen, das ist ghetto (obwohl es unwahrscheinlich ist, dass es dann einen zweiten Versuch, der jemals in der Lebenszeit des service).
for i in range(tries):
try:
name = generate_random_name()
media_storage.save(name + '.jpg', ContentFile(final_bytes))
break
except:
pass
4) In der models.py pre_save
und post_save
Signale und das aktuelle Modell ist save()
, wie kann ich feststellen, ob eine Datei kam mit der Anfrage? d.h. ich möchte wissen, ob ein neues Bild für eingehende gespeichert werden soll, oder wenn es kein Bild (einige andere Feld im Objekt wird aktualisiert und das Bild selbst bleibt unverändert).
- Dies sollte wirklich werden vier verschiedene Fragen, die Sie kennen. Es ist ein Wunder, dass Sie noch nicht angezogen, gute Stimmen! Mein Vorschlag ist, schließen Sie diese Frage jetzt. wenn Sie unzufrieden mit einer der Antworten, die Sie bekommen haben für eine particlar Punkt 1,2,3,4 poste bitte noch eine Frage, die nur mit diesem Punkt. Auf diese Weise erhalten Sie eine bessere spezifischere Antworten und Sie bekommen mehr Fragen, spezifische Fragen.
- Vielen Dank für Ihre Beratung, Ihre Lösung funktionieren würde. Ich möchte nicht schließen, diese Frage nur noch, wollen immer noch zu hören, wieder von dkarchmer re: hochladen, direkt auf S3
- Also wo hast du von hier aus gehen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sehe ich keinen Vorteil von FileField oder ImageField über das, was Sie heute tun. In der Tat, so wie ich es sehe, ist die richtige/modern/skalierbare Umgang mit uploads ist der client (browser) - upload von Dateien direkt auf S3.
Wenn es richtig gemacht wurde (von einem security-stand-Punkt), dieses Schema erlaubt das skalieren in einer unglaublichen Art und Weise, ohne die Notwendigkeit zum hinzufügen von mehr computer-power auf Ihrer Seite. Als Beispiel nehmen wir 100 Leute die das hochladen von einem Bild an der gleichen Zeit. Ihre server benötigen, erhalten Sie alle diese Daten nur hochladen, es wieder zu S3. Auf der anderen Seite, Sie können 1000 Menschen gleichzeitig hochgeladen, und ich kann Ihnen versichern, AWS und kann damit umgehen. Ihr server muss nur der Griff der Unterzeichnung der URL, das ist viel weniger Arbeit.
Werfen Sie einen Blick auf das fein-uploader, als eine gute Technik zu verwenden, um zu behandeln die effiziente upload auf s3 (laden in Blöcken, Fehlerprüfung, etc.): http://docs.fineuploader.com/endpoint_handlers/amazon-s3.html. Google "django fineuploader" finden Sie eine Beispiel-Anwendung für Django.
In meinem Fall verwende ich ein Modell mit ein paar
CharFields
(bucket
,key
) plus ein paar andere Dinge, die speziell für meine Anwendung. Meine Daten-Fluss wie folgt:get_original_url()
undget_thumbnail_url()
), so dass nach dem Upload ist es einfach für "meine Vorlagen", um die signierten Lesen-onlly URLs.Kurz gesagt, können Sie implementieren Ihre eigene version des Fineuploader wenn Sie möchten, oder verwenden Sie viele der alternativen, aber vorausgesetzt, Sie befolgen Sie die empfohlenen Sicherheits-best practices, die auf der AWS-Seite (z.B. erstellen einer speziellen IAM-nur mit schreib-Berechtigung für den AUFTRAGGEBER, selbst wenn Sie mit signierten URLs), dies, IMO, die beste Praxis für den Umgang mit uploads, vor allem, wenn Sie mit der S3 oder ähnlich speichern Sie diese Dateien.
Sorry, wenn ich nur wirklich der Beantwortung der Frage 1, aber die Fragen 2 und 3 nicht gelten, wenn Sie akzeptieren meine Antwort für die 1.
https://github.com/brunobar79/J-I-C/blob/master/src/JIC.js
, aber es scheint nicht zu sein, die meisten effizienten Algorithmus. Jetzt, mein plan ist die Implementierung der verschiedenen Methoden je nach Qualität des Uploads. Ich bin noch auf der Suche in Lambda, ich weiß nicht, ob es wird funktionieren, da diese nicht nur Kissen, sondern eine externe mozjpeg ausführbare...client->s3->lambda->s3
oderclient->s3->ec2-worker->s3
(Kein front-end-django-server auf der Schleife, die - anders als siging-URLs)1) Warum verwenden Sie ein ImageField überhaupt? Oder eher, warum verwenden Sie ein FileField?
Aber gibt es auch erhebliche Gründe, wie zB. Es ist offenbar gesichert gegen exploits und schädliche uploads?
Ja. Ich wage zu behaupten Ihre eigene code-vermutlich tut es auch, aber für einen newby mit dem FileField wird wahrscheinlich sicherzustellen, dass Ihre wichtigen system-Dateien werden nicht immer überschrieben werden, indem eine schädliche hochladen.
2) schreiben Sie in das Feld Datei?
In Ihrer situation würden Sie benötigen, um ein spezielles storage-backend, das es möglich macht, zu schreiben direkt auf den Amazon S3. Wie Sie wissen, wird der Speicher-backend für FileFile und ImageField sind steckbar. Hier ist ein Beispiel-plugin: `http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
Gibt es Beispielcode, der veranschaulicht, wie es geschrieben werden kann. Also ich wll nicht eingehen.`
3) Wie versuchen Sie, das speichern mit bestimmten Dateinamen und versuchen Sie es erneut mit einem neuen Dateinamen, wenn die, die zufällig generierte Dateiname bereits existiert?
ImageField und FileField übernimmt dies automatisch für Sie. Es wird eine neue erstellen mit dem Namen, wenn die alte existiert. Der code in meiner Antwort hier hat das automatisch, wenn ich rief immer und immer wieder. hier sind einige Beispiele von Dateinamen erzeugt (input als bada.png)
4) In der models.py pre_save und post_save Signale und in das aktuelle Modell speichern(), wie kann ich feststellen, ob eine Datei kam mit der Anfrage?
Ihre
instance.pk
werden KeineIst dies eine änderung an einer vorhandenen Datei der PK gesetzt wird.
Ist dies ein neuer Bild-upload in die
pre_save
instance.image
Arbeit? Ist das auch der richtige Weg, oder ist es so etwas wieinstance.image.file
? 3) Aber S3 Standardwerte zu überschreiben, wenn ich mich nicht Irre. Mit meiner eigenen Umsetzung, habe ich einfach die Verwendung einer anderen Instanz der storage-Klasse mit nur-schreiben-Berechtigung, aber das scheint nicht praktikabel zu sein mit ImageField. 4) ja, aber das ist undicht, die Aktualisierung eines vorhandenen Objekts mit einem neuen image umgehen würde, alle von der Verarbeitung.Nahm mich für immer um zu lernen, wie zu speichern ein Bild mit ImageField. Stellt sich heraus, es ist verrückt, einfach -- wenn man weiß, wie es zu tun, es ist, zumindest. Ich meine, es kommt alles zusammen vernünftig, nachdem Sie es sehen.
Also im Grunde, Sie arbeiten mit einem FileField. Ich sah schon in die Unterschiede zwischen ImageField und FileField:
aber ImageField nimmt auch einen width-und height-Attribut, wenn Sie angezeigt werden.
ImageField, im Gegensatz zu FileField, überprüft ein upload, so dass Sie sicher, dass es
ein Bild.
Mit ImageField kommt auf die meisten der gleichen Konstrukte wie FileField tut. Die größten Dinge zu erinnern:
So ein Formular generiert, etwas in der forms.py (oder wo auch immer Ihre Formulare) wie diesen:
In das Modell, die Sie haben könnten diese in der Korrespondenz:
imgfile = Modelle.ImageField(upload_to='images/%m/%d')
Es wird also eine POST-Anforderung von dem Benutzer (wenn der Benutzer das Formular ausfüllt). Diese Anfrage enthält im Grunde ein Wörterbuch der Daten. Das Wörterbuch hält die eingereichten Dateien. Auf focus-Anfrage auf die Datei aus dem Feld (in unserem Fall, ein ImageField), die Sie verwenden würden:
Würden Sie verwenden, wenn Sie bauen das Modell-Objekt (instanziieren Ihre model-Klasse):
Speichern, dass der einfache Weg, Sie würden nur die save () - Methode verliehen Ihr Objekt (denn Django ist, dass awesome):
Wird Ihr Bild gespeichert werden, standardmäßig in das Verzeichnis, das Sie angeben, für MEDIA_ROOT in settings.py.
Der schwierige Teil, das ist nicht wirklich so hart, wenn Sie fangen Sie auf, ist der Zugriff auf das Bild.
In Ihrer Vorlage, die Sie haben könnte so etwas wie dieses:
Where {{ MEDIA_URL }} ist so etwas wie /media/, wie angegeben in settings.py und {{ Bild.imgfile.name }} ist der name der Datei und das Unterverzeichnis angegeben, in dem Modell. "Bild" ist in diesem Fall nur das aktuelle Bild in einer Schleife von Bildern, die Sie erstellen können, um Zugriff auf jedem Bild in der Datenbank:
{% für Bild in images %}
{% endfor %}
Stellen Sie SICHER, dass Sie konfigurieren Sie die urls richtig zu handhaben das Bild oder das Bild wird nicht funktionieren. Fügen Sie diese an Ihre urls: