【问题标题】:Passing Model Field Data to Validators in Django将模型字段数据传递给 Django 中的验证器
【发布时间】:2015-12-26 02:55:50
【问题描述】:

我正在尝试为文件字段创建 MP3 验证器。验证器接收 file_path 作为参数并执行所有必要的逻辑来验证 mp3 文件。

我的问题是,当调用验证器时,我无法为函数提供整个路径。当我打印 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

【问题讨论】:

标签: python django validation


【解决方案1】:

Django 使用 audio_file 的值调用您的验证器。所以你的isMp3Valid-Validator 方法接收到一个django.db.models.fields.files.FieldFile 的实例。该类有一个名为file 的属性,即django.core.files.base.File

File 类有一个名为name 的属性。 name 的值应该是你的audio_file 的绝对路径。

你的验证器应该这样改变:

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

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

希望对你有帮助。

【讨论】:

  • 抱歉,您没有提及您使用的 Django 版本。我的答案对 Django 1.6 及更高版本有效。
  • 感谢您的回答。我现在正在使用 django 1.8,在这个版本中有什么重要的地方我应该改变吗?
  • 我用 Django 1.8 对此进行了测试。通过测试,我的意思是我检查了绝对文件路径是否已提供给您的函数。
猜你喜欢
  • 2021-05-20
  • 2019-12-24
  • 2012-03-02
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 1970-01-01
相关资源
最近更新 更多