使用Flask Restful作为大型应用程序中的蓝图

时间:2016-07-19 02:26:14

标签: flask flask-restful

我正在尝试将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>')

我做错了什么?

3 个答案:

答案 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