我正在尝试将Flask restful用作蓝图,其模式适用于其他蓝图。我一直收到以下错误消息
我收到以下错误消息
AttributeError:'Blueprint'对象没有属性'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
__初始化__。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 / __初始化__。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>')
我做错了什么?
答案 0 :(得分:2)
由于您将蓝图命名为api
,同时还使用api
中的flask_restful
对象,您遇到了麻烦。在routes.py
您明确从api
导入api/__init__.py
,这是一个Blueprint
对象。您无法向add_resource
对象调用Blueprint
,只能向Api
的{{1}}对象调用flask_restful
。
如果您将导入更改为:
from .. import api
您将导入正确的对象。我仍然建议你改变你的蓝图名称,以避免这种混乱。
答案 1 :(得分:1)
如果您遵循https://flask-restful.readthedocs.io/en/0.3.5/intermediate-usage.html
中的说明因此,您需要创建并注册api蓝图:
from flask import Flask
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 .main import main as main_blueprint
from .api import api as api_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(api_blueprint)
app.register_blueprint(api_bp)
return app
还请注意,您不再需要注册api.init_app(app)
。
答案 2 :(得分:0)
如果您要基于资源使用子模块(例如您的 / 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