You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python Magic的Django文件验证问题:文件扩展名验证报错排查

问题分析与修复方案

看起来你遇到的验证错误主要来自三个核心问题:MIME类型格式错误、验证规则与需求不匹配,以及文件指针未重置。我来帮你逐一解决:

1. 错误的MIME类型定义

你当前写的application/.mov、application/.png这类MIME格式完全不符合标准。每种文件类型都有对应的官方MIME类型,比如:

  • MP4视频:video/mp4
  • JPG图片:image/jpeg
  • PNG图片:image/png
  • MP3音频:audio/mpeg
  • ZIP压缩包:application/zip

错误的MIME类型会导致magic库返回的真实类型和你定义的不匹配,直接触发验证错误。

2. Video模型验证规则与需求不符

你提到Video模型仅接受MP4格式,但当前validate_is_video里只允许.mov后缀和对应的MIME类型,这和你的需求完全相反,需要调整为MP4的验证规则。

3. 文件指针未重置

调用file.read(1024)读取文件头部后,文件指针会停在1024字节的位置,后续Django处理文件时会无法读取完整内容,甚至引发额外错误。需要在读取后用file.seek(0)重置指针。


修复后的validators.py代码

import os
import magic
from django.core.exceptions import ValidationError

def validate_is_video(file):
    # 修正:MP4的标准MIME类型和后缀
    valid_mime_types = ['video/mp4']
    file_mime_type = magic.from_buffer(file.read(1024), mime=True)
    # 重置文件指针
    file.seek(0)
    if file_mime_type not in valid_mime_types:
        raise ValidationError('Sorry,Cannot accept unsupported file type.')
    valid_file_extensions = ['.mp4']
    ext = os.path.splitext(file.name)[1]
    if ext.lower() not in valid_file_extensions:
        raise ValidationError('Sorry,Cannot accept unacceptable file extension.')

def validate_is_image(file):
    # 修正:图片的标准MIME类型
    valid_mime_types = ['image/png', 'image/jpeg']
    file_mime_type = magic.from_buffer(file.read(1024), mime=True)
    file.seek(0)
    if file_mime_type not in valid_mime_types:
        raise ValidationError('Sorry,Cannot accept unsupported file type.')
    valid_file_extensions = ['.png', '.jpg', '.jpeg']  # 补充jpeg后缀兼容
    ext = os.path.splitext(file.name)[1]
    if ext.lower() not in valid_file_extensions:
        raise ValidationError('Sorry,Cannot accept unacceptable file extension.')

def validate_is_audio(file):
    # 修正:音频的标准MIME类型
    valid_mime_types = ['audio/mpeg', 'audio/wav']
    file_mime_type = magic.from_buffer(file.read(1024), mime=True)
    file.seek(0)
    if file_mime_type not in valid_mime_types:
        raise ValidationError('Sorry,Cannot accept unsupported file type.')
    valid_file_extensions = ['.mp3', '.wav']
    ext = os.path.splitext(file.name)[1]
    if ext.lower() not in valid_file_extensions:
        raise ValidationError('Sorry,Cannot accept unacceptable file extension.')

def validate_is_file(file):
    # 修正:压缩包的标准MIME类型
    valid_mime_types = ['application/zip', 'application/vnd.rar']
    file_mime_type = magic.from_buffer(file.read(1024), mime=True)
    file.seek(0)
    if file_mime_type not in valid_mime_types:
        raise ValidationError('Sorry,Cannot accept unsupported file type.')
    valid_file_extensions = ['.zip', '.rar']
    ext = os.path.splitext(file.name)[1]
    if ext.lower() not in valid_file_extensions:
        raise ValidationError('Sorry,Cannot accept unacceptable file extension.')

额外说明

  • 我在图片验证里补充了.jpeg后缀,因为有些工具保存的jpg文件会用这个后缀,提升兼容性;
  • RAR的标准MIME类型是application/vnd.rar,不是application/.rar,这个也需要修正;
  • 每次读取文件头部后都加上file.seek(0),确保后续Django能正常处理上传的文件。

替换完代码后,再测试上传MP4视频、JPG/PNG图片,应该就能正常通过验证了。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:22:39