简体   繁体   English

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

[英]How to serve static files in Flask with Blueprints

I had a Flask app that worked fine until, due to growth, I decided to modularize. 我有一个Flask应用程序,该应用程序运行良好,直到由于增长而决定模块化。 The new structure is as follows: 新结构如下:

├── 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:[错误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: 我尝试在实例化flask应用程序时设置static_url_path值,但是,尽管可以找到HTML文件,但我无法加载其他静态文件(如CSS和图像),因为我已定义了相对于静态文件夹的路径,如下所示: HTML:

<link href="css/bootstrap.min.css?version=24" > or <link rel="icon" href="/static/images/gear.png"> <link href="css/bootstrap.min.css?version=24" ><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. 提前致谢。

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. Jinja2 ChoiceLoader在加载程序列表中查找模板。 So first in app.jinja_loader : the template_folder directory. 因此,首先在app.jinja_loader中:template_folder目录。 Then using the FileSystemLoader in the /static directory. 然后使用/ static目录中的FileSystemLoader。 Be warn that if you have a template something.html in both the template and the static directory, the first one will be returned. 请注意,如果模板和静态目录中都包含模板something.html,则将返回第一个。

But Jinja2 has more loader than just the CoiceLoader and you should try to find one that suite your desires. 但是Jinja2不仅具有CoiceLoader,而且具有更多的加载器,您应该尝试找到适合您需求的加载器。 For exemple the DictLoader with a key 'static' could be fine also 例如,带有键“ static”的DictLoader也可以

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM