Lectura de datos de archivos durante el método de limpieza del formulario
-
25-09-2019 - |
Pregunta
Entonces, estoy trabajando para implementar la respuesta a mi pregunta anterior.
Aquí está mi modelo:
class Talk(models.Model):
title = models.CharField(max_length=200)
mp3 = models.FileField(upload_to = u'talks/', max_length=200)
Aquí está mi formulario:
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 necesita objetos similares a archivos o nombres de archivos en el disco (yo pensar): el primer caso (donde el archivo cargado es mayor que el tamaño del archivo manejado en la memoria) funciona bien, pero no sé cómo manejarlo. InMemoryUploadedFile
que entiendo lo contrario.He intentado:
# 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())
¿Hay algún problema con el mutágeno o lo estoy haciendo mal?
Después de la respuesta de Rebus
Modificando el FILE_UPLOAD_HANDLERS
poniéndose sobre la marcha en mi ModelAdmin
clase como esta:
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)
Me aparece el siguiente error 500 cuando presiono enviar:
No puede configurar los controladores de carga después de que se haya procesado la carga.
¡aunque lo haré tan pronto como pueda!
Además, no estoy seguro de tener un save
método en el objeto que estoy recuperando (he buscado en dir(self.files['mp3'].file)
y dir(self.files['mp3'])
).
Solución
Se podría tratar de cambiar su FILE_UPLOAD_HANDLERS de tal manera para Django siempre utiliza controlador de archivo temporay:
predeterminado FILE_UPLOAD_HANDLERS
:
("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
Por lo que podría dejar sólo TemporaryFileUploadHandler
reemplazando el ajuste en su settings.py.
Editar
Mucho más simple, debería haber pensado en ella en primer lugar: (:
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'])}
Se puede guardar en el disco InMemoryUploadedFile
esta manera y luego usar la ruta a ese archivo para trabajar con mutagen
.
Editar
Lo mismo sin una instancia de modelos.
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))
Tenga en cuenta que se está guardando el archivo en MEDIA_ROOT, cuando intento para guardarlo en cualquier otro lugar i get SuspiciousOperation ya que hay límites a donde se puede escribir ... debe eliminar este archivo después de examinar lo que supongo, la cosa real estará en su modelo ...
path = default_storage.delete('tmp/somename.mp3')