【发布时间】:2022-07-07 18:37:18
【问题描述】:
我想在 Python 3.7 中使用 Flask 实现一个 REST 服务器。特别是,我想将控制器(处理 URL 的那个)与业务逻辑分开,因为它对我来说似乎更易于维护。下面是代表我的代码的示例代码(尽管我实际上将它分为不同的文件和类):
#!/usr/bin/env python3
import os
os.environ["APP_SETTINGS"] = "db.config.DevelopmentConfig"
os.environ["DATABASE_URL"] = "postgresql://user_db:12341234@localhost/user_db"
os.environ["FLASK_ENV"] = "development"
from flask import Flask, request, jsonify
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app) # to handle the database transactions
class Game(db.Model):
__tablename__ = "GAME"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(40), nullable=False)
platform = db.Column(db.String(40), nullable=False)
description = db.Column(db.String(255), nullable=True)
def __init__(self, name, platform, description):
self.name = name
self.platform = platform
self.description = description
def __repr__(self):
return f"<name {self.name}>"
class GameService:
def getById(self, id: int):
entities = Game.query.filter_by(id=id)
if len(entities) > 1:
raise Exception(f"There are multiple entities with the same ID: '{id}'")
return entities.first()
def getByName(self, name: str):
entities = Game.query.filter_by(name=name).first()
if len(entities) > 1:
raise Exception(f"There are multiple entities with the same NAME: '{name}'")
return entities.first()
def create(self, name: str, platform: str, description: str):
# Build entity to persist
new_entity = Game(name=name, platform=platform, description=description)
# Create entity in DB
db.session.add(new_entity)
db.session.commit()
return new_entity.id
def update(self, entity: Game):
# Update entity in DB
db.session.merge(entity)
db.session.commit()
return entity.id
def delete(self, entity_id: int):
entities = Game.query.filter_by(id=entity_id)
if len(entities) > 1:
raise Exception(f"There are multiple entities with the same ID: '{entity_id}'")
db.session.delete(entities.first())
db.session.commit()
class GameController:
def __init__(self):
self.service = GameService()
@app.route("/v1/game/create", methods=["GET", "POST"])
def createGame(self):
try:
# Create new game in DB
entity_id = self.service.create(name=request.args.get("name"),
platform=request.args.get("platform"),
description=request.args.get("description"),
)
# Build response
response = jsonify(status="SUCCESS")
response.headers.add("Access-Control-Allow-Origin", "*")
return response
except Exception as e:
response = jsonify(status="ERROR", error_code="001")
response.headers.add("Access-Control-Allow-Origin", "*")
return response
@app.route("/v1/game/delete", methods=["GET", "POST"])
def deleteGame(self):
try:
# Create new game in DB
self.service.delete(entity_id=int(request.args.get("id")))
# Build response
response = jsonify(status="SUCCESS")
response.headers.add("Access-Control-Allow-Origin", "*")
return response
except Exception as e:
response = jsonify(status="ERROR", error_code="002")
response.headers.add("Access-Control-Allow-Origin", "*")
return response
app.run(host="127.0.0.1", port=5000, debug=True)
例如,当我进行以下调用时,问题就出现了:
http://127.0.0.1:5000/v1/game/create?name=GTA&platform=PS4&description=shooting
系统返回错误:
TypeError: createGame() missing 1 required positional argument: 'self'
我知道如果createGame 被定义为@staticmethod(因此,通过删除'self' 参数),此调用可以正常工作,但不能使用该方法中的任何类属性。
有谁知道我该如何解决这个问题?也就是说,如何定义一个烧瓶路由来使用类方法?
【问题讨论】:
标签: python flask routes flask-restful