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也可以