Django 在表单'期间读取文件数据;s清洁法

Django 在表单'期间读取文件数据;s清洁法,django,django-file-upload,mutagen,Django,Django File Upload,Mutagen,所以,我正在致力于实现这个问题的答案 这是我的模型: 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(Tal

所以,我正在致力于实现这个问题的答案

这是我的模型:

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())
诱变剂有什么问题吗,还是我做错了

在rebus的回答之后 在my
ModelAdmin
类中动态修改
文件\u上载\u处理程序
设置,如下所示:

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

您可以尝试以这种方式更改您的属性,以便Django始终使用临时文件处理程序:

文件上传\u处理程序
默认值:

("django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
因此,通过覆盖settings.py中的设置,您可以只保留
TemporaryFileUploadHandler

编辑:

简单得多,一开始就应该想到这一点:(:

您可以通过这种方式将
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中,当我尝试将其保存到其他任何位置时,因为您可以写入的位置有限制…您应该在检查后删除此文件,我想,真正的内容将出现在您的模型上

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

在我的场景中,这有点棘手,因为我实际上没有访问权限(或者更确切地说,我不想使用monkey path)相关视图,即管理员添加对象视图和更改对象视图。实际上,您可以在
ModelAdmin
定义中为该模型@rebus对这两个视图进行子类化-谢谢您的帮助,但运气不好-请参阅我的编辑。还有其他想法吗?@Dominic Rodger我编辑了一个答案,这应该更简单,结果是很容易在管理员视图(访问request.POST)的csrf保护之前更改上载处理程序。@rebus-非常好-非常感谢您帮助我解决这个问题!还没有机会尝试,但我一有机会就会告诉您!
path = default_storage.delete('tmp/somename.mp3')