在大型应用程序中使用 Flask Restful 作为蓝图
Using Flask Restful as a Blueprint in Large Application
我正在尝试使用 Flask restful 作为适用于其他蓝图的模式中的蓝图。我不断收到以下错误消息
我收到以下错误消息
AttributeError: 'Blueprint' object has no attribute 'add_resource'
我的项目设置如下:
文件夹结构
├── app
│ ├── __init__.py
│ ├── api
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── main
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ └── views.py
│ └── templates
│ ├── base.html
│ └── home.html
├── config.py
├── manage.py
└── requirements.txt
__init__.py
from flask import Flask
from flask_restful import Api
from flask_bootstrap import Bootstrap
from config import config
bootstrap = Bootstrap()
api = Api()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
api.init_app(app)
from .main import main as main_blueprint
from .api import api as api_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(api_blueprint)
return app
api/__init__.py
from flask import Blueprint
api = Blueprint('api', __name__)
from . import routes
api/routes.py
from flask_restful import Resource
from . import api
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
api.add_resource(TodoItem, '/todos/<int:id>')
我做错了什么??
由于您如何命名蓝图 api
,同时还使用 flask_restful
中的 api
对象,您 运行 遇到了麻烦。在您的 routes.py
中,您明确地从 api/__init__.py
导入 api
,这是一个 Blueprint
对象。您不能将 add_resource
调用到 Blueprint
对象,只能调用 flask_restful
中的 Api
对象。
如果您将导入更改为:
from .. import api
您将导入正确的对象。无论如何,我仍然建议更改您的蓝图名称以避免此类混淆。
如果您按照 https://flask-restful.readthedocs.io/en/0.3.5/intermediate-usage.html
中的说明进行操作
这里的关键点是创建一个 Flask Blueprint 实例并将其传递给 flask-restfuls 的 Api class.
的新实例
最后,确保在 create_app 函数中注册 flask-restful api 蓝图:app.register_blueprint(api_bp)
from flask import Flask, Blueprint
from flask_restful import Api
from flask_bootstrap import Bootstrap
from config import config
bootstrap = Bootstrap()
api_bp = Blueprint('api', __name__)
api = Api(api_bp)
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
from .users import main as users_blueprint
from .blogs import main as blogs_blueprint
# blueprints for blogs & users
app.register_blueprint(users_blueprint)
app.register_blueprint(blogs_blueprint)
app.register_blueprint(api_bp)
return app
另请注意,您不再需要注册 api.init_app(app)
。
如果你想要基于资源的子模块(比如你的 /api)...
例如:文件夹结构
├── app
│ ├── __init__.py
│ ├── foo
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── boo
│ │ ├── __init__.py
│ │ └── routes.py
├── config.py
├── manage.py
... 并使用 url_prefix 注册他们的蓝图,以便在每个添加的资源中不重复公共部分。在每个模块中创建新的 Api 实例并传递给它一个蓝图。
foo/__init__.py
from flask import Blueprint
from flask_restful import Api
foo_bp = Blueprint('foo', __name__, url_prefix='/foo')
foo_api = Api(foo_bp)
from . import routes
在路由中导入 foo_api 并向其添加资源
foo/routes.py
from flask_restful import Resource
from . import foo_api
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
foo_api.add_resource(TodoItem, '/todos/<int:id>')
然后在主应用程序中 __init__.py 只需导入模块蓝图并注册它。您甚至不需要添加“主”应用程序蓝图。如果您要从主应用程序 __init__ 导入 api,那么您无法使用它自己的参数注册每个蓝图,例如 url_prefix.
__init__.py
from flask import Flask
from config import config
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
from .foo import foo_bp
from .boo import boo_bp
app.register_blueprint(foo_bp)
app.register_blueprint(boo_bp)
return app
您可以在注册蓝图(优先)或创建蓝图时设置url_prefix。要检查路线,您可以打印 app.url_map
我正在尝试使用 Flask restful 作为适用于其他蓝图的模式中的蓝图。我不断收到以下错误消息
我收到以下错误消息
AttributeError: 'Blueprint' object has no attribute 'add_resource'
我的项目设置如下:
文件夹结构
├── app
│ ├── __init__.py
│ ├── api
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── main
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ └── views.py
│ └── templates
│ ├── base.html
│ └── home.html
├── config.py
├── manage.py
└── requirements.txt
__init__.py
from flask import Flask
from flask_restful import Api
from flask_bootstrap import Bootstrap
from config import config
bootstrap = Bootstrap()
api = Api()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
api.init_app(app)
from .main import main as main_blueprint
from .api import api as api_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(api_blueprint)
return app
api/__init__.py
from flask import Blueprint
api = Blueprint('api', __name__)
from . import routes
api/routes.py
from flask_restful import Resource
from . import api
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
api.add_resource(TodoItem, '/todos/<int:id>')
我做错了什么??
由于您如何命名蓝图 api
,同时还使用 flask_restful
中的 api
对象,您 运行 遇到了麻烦。在您的 routes.py
中,您明确地从 api/__init__.py
导入 api
,这是一个 Blueprint
对象。您不能将 add_resource
调用到 Blueprint
对象,只能调用 flask_restful
中的 Api
对象。
如果您将导入更改为:
from .. import api
您将导入正确的对象。无论如何,我仍然建议更改您的蓝图名称以避免此类混淆。
如果您按照 https://flask-restful.readthedocs.io/en/0.3.5/intermediate-usage.html
中的说明进行操作这里的关键点是创建一个 Flask Blueprint 实例并将其传递给 flask-restfuls 的 Api class.
的新实例最后,确保在 create_app 函数中注册 flask-restful api 蓝图:app.register_blueprint(api_bp)
from flask import Flask, Blueprint
from flask_restful import Api
from flask_bootstrap import Bootstrap
from config import config
bootstrap = Bootstrap()
api_bp = Blueprint('api', __name__)
api = Api(api_bp)
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
from .users import main as users_blueprint
from .blogs import main as blogs_blueprint
# blueprints for blogs & users
app.register_blueprint(users_blueprint)
app.register_blueprint(blogs_blueprint)
app.register_blueprint(api_bp)
return app
另请注意,您不再需要注册 api.init_app(app)
。
如果你想要基于资源的子模块(比如你的 /api)...
例如:文件夹结构
├── app
│ ├── __init__.py
│ ├── foo
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── boo
│ │ ├── __init__.py
│ │ └── routes.py
├── config.py
├── manage.py
... 并使用 url_prefix 注册他们的蓝图,以便在每个添加的资源中不重复公共部分。在每个模块中创建新的 Api 实例并传递给它一个蓝图。
foo/__init__.py
from flask import Blueprint
from flask_restful import Api
foo_bp = Blueprint('foo', __name__, url_prefix='/foo')
foo_api = Api(foo_bp)
from . import routes
在路由中导入 foo_api 并向其添加资源
foo/routes.py
from flask_restful import Resource
from . import foo_api
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
foo_api.add_resource(TodoItem, '/todos/<int:id>')
然后在主应用程序中 __init__.py 只需导入模块蓝图并注册它。您甚至不需要添加“主”应用程序蓝图。如果您要从主应用程序 __init__ 导入 api,那么您无法使用它自己的参数注册每个蓝图,例如 url_prefix.
__init__.py
from flask import Flask
from config import config
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
from .foo import foo_bp
from .boo import boo_bp
app.register_blueprint(foo_bp)
app.register_blueprint(boo_bp)
return app
您可以在注册蓝图(优先)或创建蓝图时设置url_prefix。要检查路线,您可以打印 app.url_map