قراءة بيانات الملف أثناء طريقة النموذج النظيفة

StackOverflow https://stackoverflow.com/questions/2806586

سؤال

لذا ، أنا أعمل على تنفيذ الإجابة سؤالي السابق.

هذا هو نموذجتي:

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

هل هناك خطأ ما في Mutagen ، أم أفعل ذلك خطأ؟

بعد إجابة ريبوس

تعديل 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 عندما أضغط على إرسال:

لا يمكنك تعيين معالجات التحميل بعد معالجة التحميل.

على الرغم من أنني أفعل ذلك في وقت مبكر قدر الإمكان!

أيضًا ، لست متأكدًا من أنني حصلت على ملف save الطريقة على الكائن الذي أعود إليه (نظرت إلى dir(self.files['mp3'].file) و dir(self.files['mp3'])).

هل كانت مفيدة؟

المحلول

يمكنك محاولة تغيير الخاص بك file_upload_handlers وبهذه الطريقة ، يستخدم Django دائمًا معالج ملفات Temporay:

FILE_UPLOAD_HANDLERS إفتراضي:

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

لذلك يمكنك المغادرة فقط 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 إلى القرص بهذه الطريقة ثم استخدم المسار إلى هذا الملف للعمل معه 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_root ، عندما أحاول حفظه في أي مكان آخر أحصل عليه مشبوهة نظرًا لوجود حدود للمكان الذي يمكنك الكتابة فيه ... يجب عليك حذف هذا الملف بعد فحصه ، أعتقد أن الشيء الحقيقي سيكون على النموذج الخاص بك ...

path = default_storage.delete('tmp/somename.mp3')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top