在写Djask过程中,在app类中添加了一个models属性app.models
。其中存储了所有用户定义的SQLAlchemy模型类,并为之实现了app.get_model_by_name()
方法,将URL中的模型类的名称字符串转换为具体的类。
现在我想要为app自动生成一个可以面向所有模型服务的api,因此我定义了一个新的蓝本admin_api
# ...
@admin_api.route("/<model>/<int:model_id>")
class ModelAPI(MethodView):
def get(self, model: str, model_id: int):
return current_app.get_model_by_name(model).query.get_or_404(model_id)
def put(self, model: str, model_id: int, data: t.Dict[str, t.Any]):
model = current_app.get_model_by_name(model)
instance = model.query.get_or_404(model_id)
for attr, value in data.items():
try:
setattr(instance, attr, value)
except Exception as e:
abort(400, str(e))
db.session.commit()
return instance
def delete(self, model: str, model_id: int):
model: t.Type[db.Model] = current_app.get_model_by_name(model)
instance = model.query.get_or_404(model_id)
db.session.delete(instance)
db.session.commit()
post方法还没有实现。
我想为这个API实现OpenAPI的spec以便能够在Swagger UI中呈现出来。
但是由于模型的名称和ID是通过URL参数传递的,无法通过@input
和@output
装饰器直接生成。
目前大概思路如下:
- 可以用
marshmallow_sqlalchemy
为每个模型类生成Schema - 再将这些Schema逐个添加到spec中,并添加对应的route(理论上可以实现因为模型类的名称已知)
上述第一步的实现可以参照文档,但是请问第二步应当怎么进行具体实现,目前没有想到好的解决办法