Lendo dados do arquivo durante o método limpo do formulário
-
25-09-2019 - |
Pergunta
Então, estou trabalhando para implementar a resposta para Minha pergunta anterior.
Aqui está o meu modelo:
class Talk(models.Model):
title = models.CharField(max_length=200)
mp3 = models.FileField(upload_to = u'talks/', max_length=200)
Aqui está minha forma:
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
Mutagênico precisa de objetos ou nomes de arquivos em forma de arquivo no disco (i acho) - O primeiro caso (onde o arquivo carregado é maior que o tamanho do arquivo tratado na memória) funciona bem, mas não sei como lidar InMemoryUploadedFile
que eu recebo o contrário. Eu tentei:
# 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())
Há algo errado com mutagênico, ou estou fazendo errado?
Após a resposta de Rebus
Modificando o FILE_UPLOAD_HANDLERS
configurando -se em minha mosca no meu ModelAdmin
aula 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 obtém o seguinte erro 500 quando eu pressiono o envio:
Você não pode configurar os manipuladores de upload após o processamento do upload.
Mesmo que eu esteja fazendo isso o mais cedo possível!
Além disso, não tenho certeza se tenho um save
método no objeto que estou voltando (eu olhei dir(self.files['mp3'].file)
e dir(self.files['mp3'])
).
Solução
Você pode tentar mudar seu File_upload_handlers De tal maneira, então o Django sempre usa o Handler de arquivos Temporay:
FILE_UPLOAD_HANDLERS
predefinição:
("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
Então você pode sair apenas TemporaryFileUploadHandler
Substituindo a configuração em seus configurações.py.
Editar:
Muito mais simples, deveria ter pensado nisso em primeiro 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'])}
Você pode salvar InMemoryUploadedFile
para o disco dessa maneira e depois use o caminho para esse arquivo para trabalhar mutagen
.
Editar:
A mesma coisa sem uma instância 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))
Observe que está salvando o arquivo em media_root, quando tento salvá -lo em qualquer outro Suspeita de operadora Como há limites para onde você pode escrever ... você deve excluir esse arquivo depois de examiná -lo, eu acho, o verdadeiro será o seu modelo ...
path = default_storage.delete('tmp/somename.mp3')