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

Django处理上传文件生成OCR输出PDF的问题求助

解决Django FieldFile转路径的OCR处理问题

你遇到的错误核心是:create_pdf_output函数需要的是字符串格式的文件系统路径,但你传入的是Django的FieldFile对象,导致类型不匹配。下面是具体的修复步骤和优化建议:

1. 核心修复:获取FieldFile的真实文件路径

Django的FieldFile对象自带path属性,它指向文件在服务器本地文件系统中的绝对路径。只需要在调用处理函数时传入这个路径即可解决类型错误:

修改models.py中的save方法

def save(self):
    # 传入FieldFile对应的绝对文件路径
    self.pdf_output = create_pdf_output(self.pdf_input.path)
    super(Document, self).save()

同步调整create_pdf_output函数的参数处理

现在函数接收的是字符串路径,开头的代码可以简化:

def create_pdf_output(pdf_path):
    # 直接使用传入的路径字符串处理
    pdf_name = os.path.splitext(pdf_path)[0] + "_out.pdf"
    pages = convert_from_path(pdf_path, 500)
    # 后续OCR处理代码保持不变...

2. 优化建议(避免后续生产问题)

你的代码还有几个潜在隐患,建议一起修复:

  • 用临时目录替代硬编码目录:
    硬编码的images和results目录会导致多用户同时操作时文件冲突,改用Python的tempfile模块创建自动销毁的临时目录:

    import tempfile
    
    def create_pdf_output(pdf_path):
        pdf_name = os.path.splitext(pdf_path)[0] + "_out.pdf"
        pages = convert_from_path(pdf_path, 500)
        
        # 创建临时图片目录,退出with块自动删除
        with tempfile.TemporaryDirectory() as img_dir:
            for ind, page in enumerate(pages):
                page.save(os.path.join(img_dir, f'out{ind}.jpg'), 'JPEG')
            
            # 创建临时结果目录
            with tempfile.TemporaryDirectory() as res_dir:
                for ind, img in enumerate(os.listdir(img_dir)):
                    img_rgb = cv2.imread(os.path.join(img_dir, img))
                    # 你的OCR模糊处理代码...
                    cv2.imwrite(os.path.join(res_dir, f'res{ind}.jpg'), img_rgb)
            
                # 从临时目录生成PDF
                with open(pdf_name, 'wb') as f:
                    imgs = [os.path.join(img_dir, fname) for fname in os.listdir(img_dir) if fname.endswith('.jpg')]
                    f.write(img2pdf.convert(imgs))
        # 临时目录自动销毁,无需手动删除
        return pdf_name
    
  • 对齐Django媒体文件规范:
    当前生成的pdf_name是绝对路径,而Django的FileField需要存储相对MEDIA_ROOT的路径。可以调整输出路径到媒体目录下:

    from django.conf import settings
    
    def create_pdf_output(pdf_path):
        input_filename = os.path.basename(pdf_path)
        output_filename = os.path.splitext(input_filename)[0] + "_out.pdf"
        # 构建符合Django媒体规范的输出路径
        output_abs_path = os.path.join(settings.MEDIA_ROOT, 'documents', 'outputs', output_filename)
        
        # 后续处理中把pdf_name替换为output_abs_path
        # ... OCR处理代码 ...
        
        # 返回相对MEDIA_ROOT的路径,供FileField存储
        return os.path.join('documents', 'outputs', output_filename)
    
  • 添加异常处理:
    OCR处理过程中可能出现文件损坏、转换失败等问题,建议添加异常捕获避免数据库保存失败:

    def save(self):
        try:
            self.pdf_output = create_pdf_output(self.pdf_input.path)
            super(Document, self).save()
        except Exception as e:
            # 可添加日志记录或自定义异常提示
            raise RuntimeError(f"OCR处理失败: {str(e)}")
    

3. 验证修复效果

修改完成后,当你创建Document实例并保存时,pdf_input的真实路径会被正确传入处理函数,解决了类型不匹配的错误,同时优化后的代码更适合生产环境的并发场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:23:13