在表单的 clean 方法期间读取文件数据

发布于 2024-09-01 09:32:28 字数 2021 浏览 1 评论 0 原文

因此,我正在努力实现我之前的问题的答案。

这是我的模型:

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 需要类似文件的对象或文件名在磁盘上(我认为) - 第一种情况(上传的文件大于内存中处理的文件的大小)工作正常,但我不知道如何处理 InMemoryUploadedFile< /code> 我否则得到的。我试过:

# 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 的回答之后,

在我的 ModelAdmin 类中动态修改 FILE_UPLOAD_HANDLERS 设置,如下所示:

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:

上传处理完成后,您无法设置上传处理程序。

即使我尽可能早地这样做!

另外,我不确定我要返回的对象是否有 save 方法(我查看过 dir(self.files['mp3'].file )dir(self.files['mp3']))。

So, I'm working on implementing the answer to my previous question.

Here's my model:

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

Here's my form:

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 needs file-like objects or filenames on disk (I think) - the first case (where the uploaded file is larger than the size of file handled in memory) works fine, but I don't know how to handle InMemoryUploadedFile that I get otherwise. I've tried:

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

Is there something wrong with mutagen, or am I doing it wrong?

After rebus' answer

Modifying the FILE_UPLOAD_HANDLERS setting on the fly in my ModelAdmin class like this:

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)

Gets me the following error 500 when I hit submit:

You cannot set the upload handlers after the upload has been processed.

even though I'm doing it as early as I possibly can!

Also, I'm not sure I've got a save method on the object I'm getting back (I've looked in dir(self.files['mp3'].file) and dir(self.files['mp3'])).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自找没趣 2024-09-08 09:32:28

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

FILE_UPLOAD_HANDLERS 默认值:

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

因此您可以通过覆盖 settings.py 中的设置只保留 TemporaryFileUploadHandler

编辑:

更简单,应该首先想到它:(:

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

请注意,当我尝试将其保存在其他地方时,它会保存SuspiciousOperation 因为您可以写入的位置有限制...您应该在之后删除此文件我想检查一下,真正的东西会在你的模型上......

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

You could try to change your FILE_UPLOAD_HANDLERS in such a way so Django always uses temporay file handler:

FILE_UPLOAD_HANDLERS default:

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

So you could leave only TemporaryFileUploadHandler by overriding the setting in your settings.py.

Edit:

Much simpler, should have thought of it at the first 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'])}

You can save InMemoryUploadedFile to the disk this way and then use the path to that file to work with mutagen.

Edit:

Same thing without a models instance.

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

Note that it's saving the file in MEDIA_ROOT, when i try to save it anywhere else i get SuspiciousOperation since there are limits to where you can write... You should delete this file after examining it i guess, the real thing will be on your model...

path = default_storage.delete('tmp/somename.mp3')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文