La lettura di file di dati durante il form pulito metodo
-
25-09-2019 - |
Domanda
Quindi, sto lavorando per implementare la risposta a la mia domanda precedente.
Ecco il mio modello:
class Talk(models.Model):
title = models.CharField(max_length=200)
mp3 = models.FileField(upload_to = u'talks/', max_length=200)
Ecco il mio form:
class TalkForm(forms.ModelForm):
def clean(self):
super(TalkForm, self).clean()
cleaned_data = self.cleaned_data
if u'mp3' in self.files:
from mutagen.mp3 import MP3
if hasattr(self.files['mp3'], 'temporary_file_path'):
audio = MP3(self.files['mp3'].temporary_file_path())
else:
# What goes here?
audio = None # setting to None for now
...
return cleaned_data
class Meta:
model = Talk
Mutageno esigenze file come oggetti o nomi di file su disco (mi pensare il primo caso (in cui il file caricato è maggiore della dimensione di file gestiti in memoria) funziona bene, ma non so come gestire InMemoryUploadedFile
che posso ottenere altrimenti.Ho provato:
# TypeError (coercing to Unicode: need string or buffer, InMemoryUploadedFile found)
audio = MP3(self.files['mp3'])
# TypeError (coercing to Unicode: need string or buffer, cStringIO.StringO found)
audio = MP3(self.files['mp3'].file)
# Hangs seemingly indefinitely on my test file (~800KB)
audio = MP3(self.files['mp3'].file.read())
C'è qualcosa di sbagliato con mutageno, o sto facendo di sbagliato?
Dopo rebus' rispondere
Modifica il FILE_UPLOAD_HANDLERS
impostazione al volo nel mio ModelAdmin
di classe come questo:
def add_view(self, request, form_url='', extra_context=None):
request.upload_handlers = [TemporaryFileUploadHandler()]
return super(TalkAdmin, self).add_view(request, form_url, extra_context)
Mi viene il seguente errore 500 quando ho colpito presentare:
Non è possibile impostare l'upload gestori dopo il caricamento è stato elaborato.
anche se sto facendo di esso il più presto possibile che io!
Inoltre, non sono sicuro, ho un save
metodo sull'oggetto, sto tornando (ho guardato in dir(self.files['mp3'].file)
e dir(self.files['mp3'])
).
Soluzione
Si potrebbe provare a cambiare il tuo FILE_UPLOAD_HANDLERS in modo Django utilizza sempre temporale gestore di file:
FILE_UPLOAD_HANDLERS
default:
("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
Così si potrebbe lasciare solo TemporaryFileUploadHandler
sovrascrivendo le impostazioni del settings.py.
Edit:
Molto più semplice, devono avere pensato al primo posto :(:
from your.models import Talk
mp3 = self.files['mp3']
f = Talk.mp3.save('somename.mp3', mp3)
MP3(f.mp3.path)
>>> {'TRCK': TRCK(encoding=0, text=[u'5'])}
È possibile salvare InMemoryUploadedFile
per il disco in questo modo e quindi utilizzare il percorso al file di lavoro con mutagen
.
Edit:
Stessa cosa senza di modelli di istanza.
import os
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.conf import settings
from mutagen.mp3 import MP3
mp3 = request.FILES['mp3'] # or self.files['mp3'] in your form
path = default_storage.save('tmp/somename.mp3', ContentFile(mp3.read()))
MP3(os.path.join(settings.MEDIA_ROOT, path))
Nota che si tratta di salvare il file in MEDIA_ROOT, quando cerco di salvare altrove, ho SuspiciousOperation poiché non ci sono limiti a dove si può scrivere...Si dovrebbe eliminare questo file, dopo l'esame, credo, la cosa reale sarà sul tuo modello...
path = default_storage.delete('tmp/somename.mp3')