2015-09-28 64 views
1

我正在嘗試爲File Field創建MP3驗證器。驗證器接收file_path作爲參數並執行所有必要的邏輯來驗證mp3文件。將模型字段數據傳遞給Django中的驗證器

我的問題是,我不能給函數的整個路徑,當驗證程序被調用。當我打印file_name變量時,我只是獲取文件的名稱而不是整個路徑。

誰能告訴我如何使用models.FileField()來訪問文件的完整路徑?

驗證:

from django.forms import ValidationError 

def isMp3Valid(file_path): 
    print (file_path) 
    is_valid = False 

    f = open(file_path, 'r') 
    block = f.read(1024) 
    frame_start = block.find(chr(255)) 
    block_count = 0 #abort after 64k 
    while len(block)>0 and frame_start == -1 and block_count<64: 
     block = f.read(1024) 
     frame_start = block.find(chr(255)) 
     block_count+=1 

    if frame_start > -1: 
     frame_hdr = block[frame_start:frame_start+4] 
     is_valid = frame_hdr[0] == chr(255) 

     mpeg_version = '' 
     layer_desc = '' 
     uses_crc = False 
     bitrate = 0 
     sample_rate = 0 
     padding = False 
     frame_length = 0 

     if is_valid: 
      is_valid = ord(frame_hdr[1]) & 0xe0 == 0xe0 #validate the rest of the frame_sync bits exist 

     if is_valid: 
      if ord(frame_hdr[1]) & 0x18 == 0: 
       mpeg_version = '2.5' 
      elif ord(frame_hdr[1]) & 0x18 == 0x10: 
       mpeg_version = '2' 
      elif ord(frame_hdr[1]) & 0x18 == 0x18: 
       mpeg_version = '1' 
      else: 
       is_valid = False 

     if is_valid: 
      if ord(frame_hdr[1]) & 6 == 2: 
       layer_desc = 'Layer III' 
      elif ord(frame_hdr[1]) & 6 == 4: 
       layer_desc = 'Layer II' 
      elif ord(frame_hdr[1]) & 6 == 6: 
       layer_desc = 'Layer I' 
      else: 
       is_valid = False 

     if is_valid: 
      uses_crc = ord(frame_hdr[1]) & 1 == 0 

      bitrate_chart = [ 
       [0,0,0,0,0], 
       [32,32,32,32,8], 
       [64,48,40,48,16], 
       [96,56,48,56,24], 
       [128,64,56,64,32], 
       [160,80,64,80,40], 
       [192,96,80,96,40], 
       [224,112,96,112,56], 
       [256,128,112,128,64], 
       [288,160,128,144,80], 
       [320,192,160,160,96], 
       [352,224,192,176,112], 
       [384,256,224,192,128], 
       [416,320,256,224,144], 
       [448,384,320,256,160]] 
      bitrate_index = ord(frame_hdr[2]) >> 4 
      if bitrate_index==15: 
       is_valid=False 
      else: 
       bitrate_col = 0 
       if mpeg_version == '1': 
        if layer_desc == 'Layer I': 
         bitrate_col = 0 
        elif layer_desc == 'Layer II': 
         bitrate_col = 1 
        else: 
         bitrate_col = 2 
       else: 
        if layer_desc == 'Layer I': 
         bitrate_col = 3 
        else: 
         bitrate_col = 4 
       bitrate = bitrate_chart[bitrate_index][bitrate_col] 
       is_valid = bitrate > 0 

     if is_valid: 
      sample_rate_chart = [ 
       [44100, 22050, 11025], 
       [48000, 24000, 12000], 
       [32000, 16000, 8000]] 
      sample_rate_index = (ord(frame_hdr[2]) & 0xc) >> 2 
      if sample_rate_index != 3: 
       sample_rate_col = 0 
       if mpeg_version == '1': 
        sample_rate_col = 0 
       elif mpeg_version == '2': 
        sample_rate_col = 1 
       else: 
        sample_rate_col = 2 
       sample_rate = sample_rate_chart[sample_rate_index][sample_rate_col] 
      else: 
       is_valid = False 

     if is_valid: 
      padding = ord(frame_hdr[2]) & 1 == 1 

      padding_length = 0 
      if layer_desc == 'Layer I': 
       if padding: 
        padding_length = 4 
       frame_length = (12 * bitrate * 1000/sample_rate + padding_length) * 4 
      else: 
       if padding: 
        padding_length = 1 
       frame_length = 144 * bitrate * 1000/sample_rate + padding_length 
      is_valid = frame_length > 0 

      # Verify the next frame 
      if(frame_start + frame_length < len(block)): 
       is_valid = block[frame_start + frame_length] == chr(255) 
      else: 
       offset = (frame_start + frame_length) - len(block) 
       block = f.read(1024) 
       if len(block) > offset: 
        is_valid = block[offset] == chr(255) 
       else: 
        is_valid = False 

    f.close() 
    if not is_valid: 
     raise ValidationError(_("El archivo no es formato MP3")) 
    return is_valid 

型號:

from django.utils.translation import ugettext as _ 
from django.db import models 
from music_manager.extra import isMp3Valid 

class Cancion(models.Model): 
    nombre = models.CharField(max_length=100,verbose_name=_("nombre")) 
    audio_file = models.FileField(upload_to="/static/audio", verbose_name=_("audio"),validators=[isMp3Valid]) 

    class Meta: 
     verbose_name_plural= "Canciones" 
     verbose_name = "Cancion" 
    # Override the __unicode__() method to return out something meaningful! 
    def __unicode__(self): 
     return self.nombre 
+0

可能的重複http://stackoverflow.com/questions/1211527/django-getting-the-absolute-path-of-a-filefield – avenet

回答

2

Django的要求與audio_file值的驗證。所以你的isMp3Valid -Validator方法接收一個django.db.models.fields.files.FieldFile的實例。該課程有一個名爲file的屬性,它是一個django.core.files.base.File

File類有一個屬性,稱爲namename的值應該是您的audio_file的絕對路徑。

您的驗證應該改變這樣的:

def is_mp3_valid(audio_file): 
    file_path = audio_file.file.name 
    is_valid = False 

    f = open(file_path, 'r') 
    .... (snip) ... 

我希望這可以幫助你。

+0

對不起,你沒有提到你正在使用的Django版本。我的答案適用於Django 1.6及更高版本。 –

+0

感謝您的回答。我現在正在使用django 1.8,在這個版本中有什麼重要的改變嗎? –

+0

我用Django 1.8測試了這個。通過測試我的意思是我檢查絕對文件路徑是給你的函數。 –

相關問題