使用相同的Python版本3.7,在本地运行渲染页面无异常,在centos服务器上渲染页面时报错jinja2.exceptions.TemplateNotFound: bootstrap/wtf.HTML
使用flask-bootstrap三方库
项目结构:
project:
APP
- auth
-views.py
-forms.py
-templates
- auth
- login.html
-static
- __init__.py
app.py
config.py
视图代码:views.py
from flask import render_template, redirect, request, url_for, flash, abort
from flask_login import login_required, login_user, logout_user, current_user
from . import auth
from .forms import LoginForm, RegistrationForm, ResetPasswordSendEmailForm, ResetNewPasswordForm, ChangePasswordForm, \
ModifyEmailForm
from .. import db
from ..models import User
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data.lower()).first()
if user is not None and user.verify_password(form.password.data):
login_user(user, form.remember_me.data)
_next = request.args.get('next')
if _next is None or not _next.startswith('/'):
_next = url_for('main.index')
return redirect(_next)
flash('Invalid username or password.')
return render_template('auth/login.html', form=form)
表单代码:forms.py
from flask_wtf import FlaskForm
from wtforms import SubmitField, StringField, PasswordField, BooleanField
from wtforms.validators import DataRequired, Length, Email, Regexp, EqualTo, ValidationError
class LoginForm(FlaskForm):
username = StringField('账号', validators=[DataRequired(), Length(1, 64)])
password = PasswordField('密码', validators=[DataRequired()])
remember_me = BooleanField('Keep me logged in')
submit = SubmitField('登录')
登录静态页:login.html
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title_content %}Login{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Login</h1>
</div>
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
工厂方法:__init__.py
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_pagedown import PageDown
from config import config
bootstrap = Bootstrap()
moment = Moment()
db = SQLAlchemy()
migrate = Migrate()
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
pagedown = PageDown()
def create_app(config_name='default'):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
moment.init_app(app)
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
pagedown.init_app(app)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
return app
启动入口代码:app.py
import os
from app import create_app, db
from app.models import User, Role
from flask_script import Manager, Shell
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
COV = None
if os.environ.get('FLASK_COVERAGE'):
import coverage
COV = coverage.coverage(branch=True, include='app/*')
COV.start()
@app.shell_context_processor
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
@manager.command
def profile(length=25, profile_dir=None):
"""Start the application under the code profiler."""
from werkzeug.middleware.profiler import ProfilerMiddleware
app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[length], profile_dir=profile_dir)
app.run()
manager.add_command('shell', Shell(make_context=make_shell_context))
if __name__ == '__main__':
manager.run()
配置文件:config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = '234sdf*^&%sfjDS,.<DSF21!'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
FLASKY_POSTS_PER_PAGE = 10
FLASKY_FOLLOWERS_PER_PAGE = 10
FLASKY_COMMENTS_PER_PAGE = 10
SQLALCHEMY_RECORD_QUERIES = True
FLASKY_SLOW_DB_QUERY_TIME = 0.5
ATTACHMENT_PATH = basedir + '/app/static'
STATIC_PATH = basedir + '/app/static/HTML/'
QR_CODE_PATH = basedir + '/app/static/QR/'
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(basedir, 'dev-data.sqlite')}"
SQLALCHEMY_TRACK_MODIFICATIONS = True
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
错误信息:
127.0.0.1 - - [16/Mar/2023 18:51:54] "GET / HTTP/1.0" 302 -
[2023-03-16 18:51:54,230] ERROR in app: Exception on /auth/login [GET]
Traceback (most recent call last):
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/app.py", line 2528, in wsgi_app
response = self.full_dispatch_request()
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/app.py", line 1825, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/app.py", line 1823, in full_dispatch_request
rv = self.dispatch_request()
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/home/sibleyAlloyWorkpieceSpecification/app/auth/views.py", line 43, in login
return render_template('auth/login.html', form=form)
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/templating.py", line 147, in render_template
return _render(app, template, context)
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/templating.py", line 130, in _render
rv = template.render(context)
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/home/sibleyAlloyWorkpieceSpecification/app/templates/auth/login.html", line 2, in top-level template code
{% import "bootstrap/wtf.HTML" as wtf %}
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/templating.py", line 61, in get_source
return self._get_source_explained(environment, template)
File "/root/.virtualenvs/venv/lib/python3.7/site-packages/flask/templating.py", line 88, in _get_source_explained
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: bootstrap/wtf.HTML