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

如何将含多子文件夹与依赖的Flask项目打包为单EXE并解决模板缺失

解决Flask项目PyInstaller单文件打包后模板找不到的问题

1. 调整Flask App的路径配置

在website/__init__.py中修改create_app函数,添加对PyInstaller单文件模式的路径适配,确保程序能找到打包后的静态文件和模板:

import os
import sys
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

db = SQLAlchemy()
DB_NAME = "database.db"

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'your-secret-key-here'
    
    # 适配PyInstaller单文件运行环境
    if getattr(sys, 'frozen', False):
        # 打包后运行时,资源会被解压到临时目录,通过sys._MEIPASS获取路径
        template_dir = os.path.join(sys._MEIPASS, 'website', 'templates')
        static_dir = os.path.join(sys._MEIPASS, 'website', 'static')
        app.template_folder = template_dir
        app.static_folder = static_dir
        # 可选:把数据库放在用户文档目录,避免权限问题
        db_path = os.path.join(os.path.expanduser('~'), 'Documents', DB_NAME)
        app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}'
    else:
        # 开发环境下使用相对路径
        app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
    
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db.init_app(app)

    from .views import views
    from .auth import auth

    app.register_blueprint(views, url_prefix='/')
    app.register_blueprint(auth, url_prefix='/')

    from .models import User, Project

    with app.app_context():
        db.create_all()

    login_manager = LoginManager()
    login_manager.login_view = 'auth.login'
    login_manager.init_app(app)

    @login_manager.user_loader
    def load_user(id):
        return User.query.get(int(id))

    return app

2. 修正PyInstaller打包命令

调整资源文件的映射路径,确保打包后资源结构与代码中的路径匹配,同时修正主文件路径:

# Windows环境命令
pyinstaller --onefile ^
--add-data "website/templates;website/templates" ^
--add-data "website/static;website/static" ^
--hidden-import flask_sqlalchemy ^
--hidden-import flask_login ^
--hidden-import werkzeug.security ^
--hidden-import sqlalchemy.sql ^
--hidden-import json ^
--hidden-import base64 ^
main.py

说明:

  • Linux/macOS环境下,把路径分隔符;换成:
  • --add-data的目标路径保留website/前缀,和代码中sys._MEIPASS/website/templates的路径对应
  • 主文件是根目录的main.py,而非website/main.py

3. 错误原因解析

  • 原命令主文件路径错误:指定了website/main.py,但实际主文件在根目录,导致打包结构混乱
  • 资源映射路径错误:原命令把模板放到了根目录templates,但代码中期望从website/templates读取,导致Flask找不到模板
  • 未适配单文件模式:PyInstaller单文件运行时会把资源解压到临时目录,必须通过sys._MEIPASS获取正确路径,否则相对路径失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:33:20