【问题标题】:Working with Flask routes in Python classes在 Python 类中使用 Flask 路由
【发布时间】: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


    【解决方案1】:

    我觉得flask的pluggable views应该可以解决你的问题。

    另一种选择是扩展名flask-classful。不过我没有这方面的经验。

    【讨论】:

      猜你喜欢
      • 2021-09-05
      • 2022-09-27
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多