问题描述
对于使用 flask
flask-restx
应用,我有以下项目结构
.
├── app
│ ├── extensions.py
│ ├── __init__.py
│ └── pv_dimensioning
│ ├── controller.py
│ ├── __init__.py
│ ├── models
│ │ ├── dto.py
│ │ ├── __init__.py
│ │ └── vendor_models.py
│ ├── services
│ │ ├── calculator.py
│ │ ├── database.py
│ │ ├── data.py
│ │ ├── db_crud.py
│ │ ├── __init__.py
│ │ └── processor.py
│ └── utils
│ ├── decode_verify_jwt.py
│ ├── decorator.py
│ └── __init__.py
├── config.py
├── main.py
├── package.json
├── package-lock.json
├── Pipfile
├── Pipfile.lock
├── README.md
├── serverless.yml
└── tests
├── __init__.py
├── test_calculator.py
├── test_config.py
└── test_processor.py
在 controller.py
中,我添加了 add_argument()
语句并在 api 路由中解析它们。在 add_argument()
语句之一中,我想为用户添加 choices
。为了获得选择,我从数据库中查询并获取可用值的 list
。然后我将此 list
转换为 tuple
,将其分配给变量,并将其作为 choices
参数传递给 add_argument()
我的代码:
data.py
from ..models.vendor_models import Adminvendor
def data(app):
values = Adminvendor.query.all()
v = [value.name for value in values]
return {'v': tuple(v)}
controller.py
from flask_restx import Resource,reqparse
parser = reqparse.RequestParser()
parser.add_argument(
"vendor",choices=vendors,# <--- The values of v should be added here
help="Select the vendor"
)
@ns.route("/")
class UserOutput(Resource):
@ns.doc(
"Get calculated response",responses={
200: "Values returned",400: "Validation Error",403: "Not authorized"
},)
@ns.expect(parser,validation=True)
def get(self):
args = parser.parse_args()
return Dimensioncalculator.inputs(**args),200
其中 ns
是 namespace
。
我在 __init__.py
文件夹中的 app
文件如下:
from flask import Flask
from .extensions import cors,db,ma
def create_app(app_config):
app = Flask(__name__)
app.config.from_object(app_config)
register_blueprints(app)
register_extensions(app)
return app
def register_extensions(app):
cors.init_app(app)
db.init_app(app)
ma.init_app(app)
def register_blueprints(app):
from .pv_dimensioning import dimensioning_blueprint
app.register_blueprint(dimensioning_blueprint)
应用的入口点是 main.py
import os
from app import create_app
from app.extensions import db
from app.pv_dimensioning.services.data import data
from config import config_by_name
config_name = os.getenv("FLASK_CONfig") or "default"
app_config = config_by_name[config_name]
app = create_app(app_config)
db.create_all(app=app)
with app.app_context():
v = data(app)
print(v)
print(v)
的输出如下:
{'v': ('Solarmodul Canadian Solar HiKu CS3L-370MS 370Wp','Solarmodul Longi LR4-60HIH-370M,370Wp','Solarmodul Solar Fabrik mono S3 - Halfcut 360Wp','Solarmodul Energetica e.Classic M HC black - 360Wp','Solarmodul Yingli YL280P-29b-YGE 60 Cell Series 2 - poly,280Wp','Solarmodul Suntech Power STP370S-B60/Wnh,'Solarmodul AXITEC AXIworldpremium X HC AC-340MH/120S,340Wp','Solarmodul Longi LR4-72HIH-440M,440Wp','Solarmodul Seraphim SRP-330-BMB-DG 330Wp','Solarmodul Sharp NU-JD 440Wp')}
我希望在 v
参数的 controller.py
中使用这些 'vendor'
值。
我尝试通过在 v
中添加 main.py
来从 from main import v
获取 controller.py
的值,但它显示以下错误
ImportError: cannot import name 'v' from 'main'
我做错了什么?
感谢任何帮助。
谢谢
解决方法
我不是 flask_restx
方面的专家,但根据我的理解,choices
参数采用可迭代对象,因此您应该能够简单地传递 data
的返回值功能。
数据.py
from ..models.vendor_models import AdminVendor
def data():
values = AdminVendor.query.all()
v = [value.name for value in values]
return {'v': tuple(v)}
控制器.py
from flask_restx import Resource,reqparse
from .services.data import data
parser = reqparse.RequestParser()
parser.add_argument(
"vendor",choices=data()['v'],help="Select the vendor")
关于导入错误,Mindslave 指出这很可能是循环导入错误,请参阅此 question 以了解更多详细信息。通常,这些可以通过将导入从模块顶部移到函数/类中来避免,例如:
from flask_restx import Resource,reqparse
def load_parser():
from .services.data import data # avoid circular import
parser = reqparse.RequestParser()
parser.add_argument(
"vendor",help="Select the vendor")
return parser
parse = load_parser()
附带说明,请注意 reqparse
计划从flask_restx 中删除,因此在您深入了解它之前可能值得考虑一个不同的选项:
警告 Flask-RESTX 的整个请求解析器部分预定用于 删除并将被有关如何与 其他可以更好地处理输入/输出的包(例如 棉花糖)。这意味着它会一直维持到 2.0 但 认为它已弃用。别担心,如果你现在有使用它的代码 并希望继续这样做,它也不会消失 很快。
来源:https://flask-restx.readthedocs.io/en/latest/parsing.html