如何使用蓝图在Flask中提供静态文件

时间:2022-04-27 16:53:37

I had a Flask app that worked fine until, due to growth, I decided to modularize. The new structure is as follows:

我有一个Flask应用程序工作正常,直到由于增长,我决定模块化。新结构如下:

├── Dockerfile
├── README.md
├── app
│   ├── __init__.py
│   ├── config.py
│   ├── cron.py
│   ├── database.ini
│   ├── db.py
│   ├── db.sqlite3
│   └── webapp
│       ├── __init__.py
│       └── routes.py
├── db.sqlite3
├── docker-compose.yml
├── error.log
├── gunicorn_config.py
├── rd.py
├── requirements.txt
├── static
│   ├── css
│   │   └── bootstrap.min.css
│   ├── data.html
│   ├── fonts
│   │   ├── glyphicons-halflings-regular.eot
│   │   ├── glyphicons-halflings-regular.svg
│   │   ├── glyphicons-halflings-regular.ttf
│   │   ├── glyphicons-halflings-regular.woff
│   │   └── glyphicons-halflings-regular.woff2
│   ├── images
│   │   ├── ajax-loader.gif
│   │   ├── gear.png
│   │   ├── gear_small.png
│   │   └── logo.png
│   ├── index.html
│   ├── js
│   │   ├── app.js
│   │   ├── bootbox.min.js
│   │   ├── bootstrap.js
│   │   ├── bootstrap.min.js
│   │   └── npm.js
│   ├── login.html
│   ├── manage_users.html
│   ├── register.html
│   ├── reset_password.html
│   ├── settings.html
│   └── upload.html
└── templates
    └── base.html

Here is the __init__.py for webapp:

这是webapp的__init__.py:

from flask import Flask
from app.config import DebugConfig
from flask_sqlalchemy import SQLAlchemy
from importlib import import_module
from logging import basicConfig, DEBUG, getLogger, StreamHandler
import os

import uuid

def register_blueprints(app):
    for module_name in (app.config['MODULES']):
        module = import_module('app.{}.routes'.format(module_name))
        app.register_blueprint(module.blueprint)

def configure_logs(app):
    basicConfig(filename='error.log', level=DEBUG)
    logger = getLogger()
    logger.addHandler(StreamHandler())

def create_app():
    file = (__file__)
    app = Flask(__name__)
    app.secret_key = str(uuid.uuid4())
    app.config.from_object(DebugConfig)
    register_blueprints(app)
    configure_logs(app)

    return app

Here is login page route code:

这是登录页面路由代码:

@blueprint.route("/login", methods=["GET", "POST"])
def login():

    if request.method == 'GET':
        return render_template(url_for('static', filename='login.html')

Unfortunately this new structure leads to this error when I attempt to serve the app:

不幸的是,当我尝试提供应用时,这个新结构会导致此错误:

builtins.FileNotFoundError FileNotFoundError: [Errno 2] No such file or directory: '/static/login.html'

builtins.FileNotFoundError FileNotFoundError:[Errno 2]没有这样的文件或目录:'/ static / login.html'

I have been messing with this for a while now and just can't figure out how to get the app to work and manage to locate the files. I tried setting the static_url_path value when instantiating the flask app but, although that manages to locate the HTML files, I'm unable to load the other static files like CSS and images because I have my paths defined relative to the static folder as below in the HTML:

我现在已经搞砸了一段时间,只是无法弄清楚如何让应用程序工作并设法找到文件。我在实例化烧瓶应用程序时尝试设置static_url_path值,但是虽然设法找到HTML文件,但我无法加载其他静态文件,如CSS和图像,因为我的路径相对于静态文件夹定义如下HTML:

<link href="css/bootstrap.min.css?version=24" > or <link rel="icon" href="/static/images/gear.png">

Please assist, I feel like I'm going to pull my hair out as I've spent too much time on this issue. Thanks in advance.

请帮忙,因为我在这个问题上花了太多时间,所以我觉得我要拔掉头发。提前致谢。

1 个解决方案

#1


0  

What your are looking for is the Flask jinja_loader.

您正在寻找的是Flask jinja_loader。

In your create_app method, you could overwrite the jinja_loader provided by default for Flask, which look into the template_folder directory to search for file using render_template method.

在create_app方法中,您可以覆盖Flask默认提供的jinja_loader,它会查看template_folder目录以使用render_template方法搜索文件。

def create_app():
    file = (__file__)
    app = Flask(__name__)
    app.secret_key = str(uuid.uuid4())
    app.config.from_object(DebugConfig)
    register_blueprints(app)
    configure_logs(app)

    # Overwrite Flask jinja_loader, using ChoiceLoader
    template_loader = jinja2.ChoiceLoader([
        app.jinja_loader,
        jinja2.FileSystemLoader('/path/to/static'),
    ])
    app.jinja_loader = template_loader

    return app

Jinja2 ChoiceLoader look for template in the list of loaders. So first in app.jinja_loader : the template_folder directory. Then using the FileSystemLoader in the /static directory. Be warn that if you have a template something.html in both the template and the static directory, the first one will be returned.

Jinja2 ChoiceLoader在加载器列表中查找模板。首先在app.jinja_loader中:template_folder目录。然后使用/ static目录中的FileSystemLoader。请注意,如果模板和静态目录中都有模板something.html,则会返回第一个模板。

But Jinja2 has more loader than just the CoiceLoader and you should try to find one that suite your desires. For exemple the DictLoader with a key 'static' could be fine also

但是Jinja2有更多的装载机而不仅仅是CoiceLoader,你应该尝试找到满足你需求的装载机。例如,带有“静态”键的DictLoader也可以

#1


0  

What your are looking for is the Flask jinja_loader.

您正在寻找的是Flask jinja_loader。

In your create_app method, you could overwrite the jinja_loader provided by default for Flask, which look into the template_folder directory to search for file using render_template method.

在create_app方法中,您可以覆盖Flask默认提供的jinja_loader,它会查看template_folder目录以使用render_template方法搜索文件。

def create_app():
    file = (__file__)
    app = Flask(__name__)
    app.secret_key = str(uuid.uuid4())
    app.config.from_object(DebugConfig)
    register_blueprints(app)
    configure_logs(app)

    # Overwrite Flask jinja_loader, using ChoiceLoader
    template_loader = jinja2.ChoiceLoader([
        app.jinja_loader,
        jinja2.FileSystemLoader('/path/to/static'),
    ])
    app.jinja_loader = template_loader

    return app

Jinja2 ChoiceLoader look for template in the list of loaders. So first in app.jinja_loader : the template_folder directory. Then using the FileSystemLoader in the /static directory. Be warn that if you have a template something.html in both the template and the static directory, the first one will be returned.

Jinja2 ChoiceLoader在加载器列表中查找模板。首先在app.jinja_loader中:template_folder目录。然后使用/ static目录中的FileSystemLoader。请注意,如果模板和静态目录中都有模板something.html,则会返回第一个模板。

But Jinja2 has more loader than just the CoiceLoader and you should try to find one that suite your desires. For exemple the DictLoader with a key 'static' could be fine also

但是Jinja2有更多的装载机而不仅仅是CoiceLoader,你应该尝试找到满足你需求的装载机。例如,带有“静态”键的DictLoader也可以