代码之家  ›  专栏  ›  技术社区  ›  Dominic Rodger

在窗体清理方法期间读取文件数据

  •  14
  • Dominic Rodger  · 技术社区  · 16 年前

    所以,我正在努力实现 my previous question .

    这是我的模型:

    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
    

    Mutagen 需要磁盘上的对象或文件名之类的文件(i 认为 )-第一种情况(上载的文件大于内存中处理的文件的大小)很好,但我不知道如何处理 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())
    

    诱变剂有问题吗?还是我做错了?

    在Rebs的回答之后

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

    当我点击Submit时,获取以下错误500:

    处理上载后,无法设置上载处理程序。

    即使我尽可能早的做了!

    另外,我不确定我有 save 我要回去的对象的方法 dir(self.files['mp3'].file) dir(self.files['mp3']) )

    1 回复  |  直到 16 年前
        1
  •  23
  •   Dominic Rodger    16 年前

    你可以尝试改变你的 FILE_UPLOAD_HANDLERS 这样,Django总是使用临时文件处理程序:

    FILE_UPLOAD_HANDLERS 违约:

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

    所以你只能离开 TemporaryFileUploadHandler 通过覆盖settings.py中的设置。

    编辑:

    更简单的是,首先应该想到的是:(1)

    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 以这种方式到达磁盘,然后使用该文件的路径 mutagen .

    编辑:

    同样的事情没有模型实例。

    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_根目录中,当我尝试将其保存到其他任何位置时 SuspiciousOperation 既然你能写的地方有限制…你应该在检查完这个文件后删除它,我想真正的东西会在你的模型上…

    path = default_storage.delete('tmp/somename.mp3')