python-3.x - 应用程序工厂模式:AttributeError:“元组”对象没有属性“shell_context_processor”
问题描述
我正在尝试将我的 Flask 应用程序转换为 App Factory Pattern,但我遇到了以下错误:
Traceback (most recent call last):
File "/usr/local/bin/flask", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/decorators.py", line 73, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 848, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 305, in __init__
self._load_unlocked()
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
File "/home/chrdina/python/werda/werda.py", line 7, in <module>
@app.shell_context_processor
AttributeError: 'tuple' object has no attribute 'shell_context_processor'
我试图找出 AttributeError 发生在哪里,但我完全被困住了。我不明白提到的元组在我的代码中的位置。我尝试删除 shell_context_processor 部分,但随后该应用程序似乎根本不知道它是一个应用程序并抛出 this "Error: Failed to find Flask application or factory in module "werda". Use "FLASK_APP=werda:name to specify one.")
。
如果我然后尝试FLASK_APP
再次导出(它已经在我的 中设置.flaskenv
)没有任何变化。
werda.py
我在我的目录顶层(这是我的应用程序)中定义了 shell_context_processor 。
werda.py:
from app import create_app, db
from app.models import User, Role, Employee, Language, Employee_Languages, Attendance, AttendanceArchive
app = create_app()
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User, 'Role': Role, 'Employee':Employee, 'Language':Language, 'Employee_Languages':Employee_Languages, 'Attendance':Attendance, 'AttendanceArchive':AttendanceArchive}
初始化.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_bootstrap import Bootstrap
from flask_security import Security, SQLAlchemyUserDatastore
from flask_mail import Mail
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security()
mail = Mail()
admin = Admin()
def create_app(config_class=Config):
app=Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
migrate.init_app(app, db)
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security.init_app(app, user_datastore)
bootstrap.init_app(app)
mail.init_app(app)
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
admin = Admin(app, name='werda', template_mode='bootstrap3')
#send errors via mail:
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='no-reply@' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'], subject='werda Failure',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#save errors to log file:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/werda.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('werda startup')
return app, admin
from app import models
目录结构
.
├── app
│ ├── cli.py
│ ├── errors
│ │ ├── handlers.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── main
│ │ ├── forms.py
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ └── routes.py
│ ├── models.py
│ └── templates
│ ├── addnextweek.html
│ ├── base.html
│ ├── errors
│ │ ├── 403.html
│ │ ├── 404.html
│ │ └── 500.html
│ ├── index.html
│ ├── movetoarchive.html
│ ├── nextweek.html
│ ├── now.html
│ ├── russ.html
│ ├── security
│ │ ├── login_user.html
│ │ └── register_user.html
│ ├── thisweek.html
│ ├── thisweek_working.html
│ └── today.html
├── app.db
├── config.py
├── libc6_2.31-0ubuntu8+lp1871129~1_amd64.deb
├── README.md
├── requirements.txt
├── werda.py
解决方案
我知道了!我在 create_app() 中返回了应用程序和管理员,这导致了问题。似乎这也是神秘元组所在的地方。如果 create_app() 只返回应用程序,我的应用程序将按原样启动。现在来研究如何正确运行flask-admin。现在更正代码: init .py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_bootstrap import Bootstrap
from flask_security import Security, SQLAlchemyUserDatastore
from flask_mail import Mail
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security()
mail = Mail()
admin = Admin()
def create_app(config_class=Config):
app=Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
migrate.init_app(app, db)
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security.init_app(app, user_datastore)
bootstrap.init_app(app)
mail.init_app(app)
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
admin = Admin(app, name='werda', template_mode='bootstrap3')
#send errors via mail:
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='no-reply@' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'], subject='werda Failure',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#save errors to log file:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/werda.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('werda startup')
return app #deleted admin here
from app import models
推荐阅读
- awk - 如何通过使用awk忽略带有字符的行来找到该字段的最大值?
- angular - 我有这部分代码的解释吗?
- node.js - 网络错误:无法获取离子反应
- jsf - 由于 javax.faces.ViewState,无法从 Postman 加载网页?
- java - 使用 openapi-generator-gradle-plugin 只为 spring boot 生成 REST 接口
- python - 如何动态过滤 Pandas 数据框中的数据?
- javascript - 唯一数组Javascript中具有不同键的数组列表
- python - 处理 pandas Dataframe 中的 no-List
- java - 如何使用 Retrofit 从 OpenWeatherMap API 获取“天气”对象数据
- c# - 使用 DLLImport 从 C# 调用 c++,找不到对象引用错误