Django uploads: Wirf hochgeladen von Duplikaten verwenden vorhandene Datei (md5-basierte check)
Habe ich ein Modell mit einer FileField
ist, die hält Benutzer hochgeladenen Dateien. Da ich Platz sparen wollen, würde ich mag, um Duplikate zu vermeiden.
, Was möchte ich erreichen:
- Berechnen die hochgeladenen Dateien md5-Prüfsumme
- Speichern Sie die Datei mit der file name basiert auf seiner md5sum
- Wenn eine Datei mit diesem Namen ist bereits vorhanden (die neue Datei ist ein doppelte), verwerfen die hochgeladene Datei und die vorhandene Datei verwenden, anstatt
1 und 2 ist bereits in Arbeit, aber wie würde ich vergessen das hochgeladen zu duplizieren und nutzen Sie die vorhandene Datei ersetzen?
Hinweis, dass ich gern die vorhandene Datei und nicht überschrieben (hauptsächlich, um die geänderte Zeit das gleiche - besser für die Datensicherung).
Hinweise:
- Ich bin mit Django 1.5
- Der upload-handler ist
django.core.files.uploadhandler.TemporaryFileUploadHandler
Code:
def media_file_name(instance, filename):
h = instance.md5sum
basename, ext = os.path.splitext(filename)
return os.path.join('mediafiles', h[0:1], h[1:2], h + ext.lower())
class Media(models.Model):
orig_file = models.FileField(upload_to=media_file_name)
md5sum = models.CharField(max_length=36)
...
def save(self, *args, **kwargs):
if not self.pk: # file is new
md5 = hashlib.md5()
for chunk in self.orig_file.chunks():
md5.update(chunk)
self.md5sum = md5.hexdigest()
super(Media, self).save(*args, **kwargs)
Jede Hilfe ist willkommen!
- Wie viel Verkehr wollen Sie die bekommen? Wenn es ein kleines Projekt oder ein eigenes Projekt haben, können Sie berappen die $0,50/Monat bei Amazon S3 oder Rackspace Cloudfiles, oder jede andere Billig filestore gibt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dank alTus Antwort, ich war in der Lage, herauszufinden, dass das schreiben eine custom storage class ist der Schlüssel, und es war einfacher als erwartet.
_save
Methode, eine Datei zu schreiben, wenn es schon da ist und ich einfach nur wieder die Namen.get_available_name
zu vermeiden, immer zahlen an den Dateinamen angehängt, wenn eine Datei mit demselben Namen bereits vorhanden istIch weiß nicht, ob dies ist die richtige Weg, es zu tun, aber es funktioniert gut so weit.
Hoffe, dies ist nützlich!
Hier ist der komplette Beispielcode:
AFAIK kann man nicht einfach implementieren, diese mit save/delete-Methoden coz-Dateien behandelt werden, ganz speziell.
Aber Sie könnten versuchen, etwas, wie, dass.
Erste, meine einfache md5-Datei-hash-Funktion:
Nächsten
simple_upload_to
ist smth like yours media_file_name Funktion.Sie sollten es verwenden, wie:
Natürlich, es ist nur ein Beispiel, damit Pfad-Generierung Logik könnten verschiedene.
Und der wichtigste Teil:
Wie Sie sehen können diese benutzerdefinierte Speicher-löscht die Datei vor dem speichern, und speichert dann neue mit dem gleichen Namen.
Hier können Sie also implementieren, die Ihre Logik wenn NICHT löschen (und damit die Aktualisierung) der Dateien ist wichtig.
Mehr über Speicher ou finden Sie hier: https://docs.djangoproject.com/en/1.5/ref/files/storage/
Ich hatte das gleiche Problem und fand diese Frage ALSO. Als dies nichts ist zu ungewöhnlich, suchte ich im web und fand das folgende Python-Paket, das die Nahten genau das zu tun, was Sie wollen:
https://pypi.python.org/pypi/django-hashedfilenamestorage
Wenn SHA1-hashes sind nicht in Frage, ich denke, eine pull-Anforderung hinzufügen MD5-hashing-Unterstützung wäre eine tolle Idee.
Diese Antwort hat mir geholfen, das problem zu lösen, wo ich gerne eine Ausnahme auslösen, wenn die Datei, die hochgeladen wird, die bereits existiert. Diese version löst eine Ausnahme aus, wenn eine Datei mit demselben Namen bereits im upload-Speicherort.
Daten geht von der template -> Formen -> Aussicht -> db(Modell). Macht es Sinn, stoppen Sie die Duplikate bei den frühesten Schritt selbst. In diesem Fall forms.py.
Referenz: http://josephmosby.com/2015/05/13/preventing-file-dupes-in-django.html