Чтение данных файла во время чистого метода формы

Так, я работаю над реализацией ответа на мой предыдущий вопрос.

Вот моя модель:

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

Вот моя форма:

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

Мутагену нужны подобные файлу объекты или имена файлов на диске (я думаю) - первый случай (где загруженный файл больше, чем размер файла, обработанного в памяти), хорошо работает, но я не знаю, как обработать InMemoryUploadedFile то, что я добираюсь иначе. Я попробовал:

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

Есть ли что-то не так с мутагеном, или я делаю его неправильно?

После ответа ребуса

Изменение FILE_UPLOAD_HANDLERS установка на лету в моем ModelAdmin класс как это:

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)

Получает меня следующая ошибка 500, когда я совершил нападки, отправьте:

Вы не можете установить обработчики загрузок после того, как загрузка была обработана.

даже при том, что я уже делаю его, я возможно могу!

Кроме того, я не уверен, что у меня есть a save метод на объекте, который я возвращаю (я заглянул dir(self.files['mp3'].file) и dir(self.files['mp3'])).

16
задан Community 23 May 2017 в 10:31
поделиться

1 ответ

Вы можете попробовать изменить свои FILE_UPLOAD_HANDLERS таким образом, чтобы Django всегда использовал обработчик временных файлов:

FILE_UPLOAD_HANDLERS по умолчанию:

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

Таким образом, вы могли оставить только TemporaryFileUploadHandler , отменив настройку в файле settings.py.

Изменить:

Гораздо проще, нужно было подумать об этом с самого начала: (:

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

Вы можете сохранить InMemoryUploadedFile на диск таким образом, а затем использовать путь к этому файлу для работать с мутагеном .

Изменить:

То же самое без экземпляра модели.

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

Обратите внимание, что он сохраняет файл в MEDIA_ROOT, когда я пытаюсь сохранить его где-нибудь еще, я получаю SuspiciousOperation , поскольку есть ограничения на то, где вы можете писать ... Вы должны удалить этот файл после его изучения, я думаю, настоящая вещь будет на вашей модели ...

path = default_storage.delete('tmp/somename.mp3')
25
ответ дан 30 November 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: