Question

Alors, je travaille sur la mise en œuvre de la réponse à href="https://stackoverflow.com/questions/2798670/processing-file-uploads-before-object-is-saved"> .

Voici mon modèle:

class Talk(models.Model):
  title        = models.CharField(max_length=200)
  mp3          = models.FileField(upload_to = u'talks/', max_length=200)

Voici ma forme:

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ène a besoin des objets semblables aux fichiers ou les noms de fichiers sur le disque (I < em> penser ) - le premier cas (où le fichier téléchargé est plus grande que la taille du fichier manipulé en mémoire) fonctionne très bien, mais je ne sais pas comment gérer InMemoryUploadedFile que je reçois autrement. J'ai essayé:

# 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())

Y at-il quelque chose de mal avec Mutagène, ou que je fais mal?

Après rébus réponse

Modification du paramètre FILE_UPLOAD_HANDLERS à la volée dans ma classe ModelAdmin comme ceci:

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 fait l'erreur suivante 500 quand je frappe présenter:

  

Vous ne pouvez pas définir les gestionnaires de téléchargement après le téléchargement a été traité.

même si je le fais dès que je le peux!

En outre, je ne suis pas sûr que j'ai une méthode save sur l'objet Je reviens (je l'ai regardé dans dir(self.files['mp3'].file) et dir(self.files['mp3'])).

Était-ce utile?

La solution

Vous pouvez essayer de changer votre FILE_UPLOAD_HANDLERS de telle manière si Django utilise toujours gestionnaire de fichiers Temporaire de:

default FILE_UPLOAD_HANDLERS:

("django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler",)

Vous pouvez laisser seulement TemporaryFileUploadHandler en remplaçant le paramètre dans votre settings.py.

Modifier

Beaucoup plus simple, aurait pensé à la première place: (:

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'])}

Vous pouvez enregistrer InMemoryUploadedFile sur le disque de cette façon, puis utiliser le chemin vers ce fichier pour travailler avec mutagen.

Modifier

Même chose sans une instance de modèles.

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))

Notez qu'il est d'enregistrer le fichier dans MEDIA_ROOT, lorsque je tente de le sauver nulle part ailleurs je reçois SuspiciousOperation car il y a des limites à l'endroit où vous pouvez écrire ... vous devez supprimer ce fichier après l'avoir examiné, je suppose, la vraie chose sera sur votre modèle ...

path = default_storage.delete('tmp/somename.mp3')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top