3

Flaskでは、ルートにクラスとデコレータを使用できます。それぞれのユースケースの利点は何でしょうか?

静的ページのデコレータと、より動的なページのクラスを考えていました。竜巻/gunicornをフラスコと組み合わせる場合は、これがより良い方法です。

非同期メソッドを使用することを計画しています。これを例として 使用して、 FlaskとTornadoを一緒に使用しますか?

この投稿では、フレームワークに依存する可能性があると述べていますが、フラスコでは両方を使用できます。
PythonWeb開発におけるデコレータとクラス

4

2 に答える 2

2

これらは私の個人的な経験則です。

  1. 既存のアプリケーションから移植する必要がある場合は、ソース アプリケーションで使用されている規則を使用します。2 つの可能なルーティング スタイルがあることは大きな利点です。
  2. アプリケーションが同じコードに対して異なる URL を使用する場合、URL とハンドラー クラスの間に明示的なマッピングを作成します。
  3. アプリケーションで使用する URL とクラスの数が少ない場合は、デコレーターを使用します。
  4. アプリケーションが複雑で URL が複雑な場合は、URL とハンドラー クラス間のマッピングを作成します。
于 2012-09-11T16:18:40.840 に答える
1

以下の MVP コードに見られるように、REST API 動詞の多くを実装する場合、ほとんどの場合、データベース テーブルのようなリソースの周りに、クラス ベースのルートが好きです。これは、他のデコレーターを使用する場合の明確化にも役立ちます。また、特定のデコレーターを持つ動詞を選択することもできます。

別の方法として、装飾されたメソッドを使用して、静的ページの html を返すルートを実装します。本当に必要なのは GET 動詞だけです。

from flask import Flask
from flask_restful import Api, Resource, reqparse, abort, fields, marshal_with
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)

class VideoModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    views = db.Column(db.Integer, nullable=False)
    likes = db.Column(db.Integer, nullable=False)

    def __repr__(self):
        return f"Video(name = {name}, views = {views}, likes = {likes})"

video_put_args = reqparse.RequestParser()
video_put_args.add_argument("name", type=str, help="Name of the video is required", required=True)
video_put_args.add_argument("views", type=int, help="Views of the video", required=True)
video_put_args.add_argument("likes", type=int, help="Likes on the video", required=True)

video_update_args = reqparse.RequestParser()
video_update_args.add_argument("name", type=str, help="Name of the video is required")
video_update_args.add_argument("views", type=int, help="Views of the video")
video_update_args.add_argument("likes", type=int, help="Likes on the video")

resource_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'views': fields.Integer,
    'likes': fields.Integer
}

class Video(Resource):
    @marshal_with(resource_fields)
    def get(self, video_id):
        result = VideoModel.query.filter_by(id=video_id).first()
        if not result:
            abort(404, message="Could not find video with that id")
        return result

    @marshal_with(resource_fields)
    def put(self, video_id):
        args = video_put_args.parse_args()
        result = VideoModel.query.filter_by(id=video_id).first()
        if result:
            abort(409, message="Video id taken...")

        video = VideoModel(id=video_id, name=args['name'], views=args['views'], likes=args['likes'])
        db.session.add(video)
        db.session.commit()
        return video, 201

    @marshal_with(resource_fields)
    def patch(self, video_id):
        args = video_update_args.parse_args()
        result = VideoModel.query.filter_by(id=video_id).first()
        if not result:
            abort(404, message="Video doesn't exist, cannot update")

        if args['name']:
            result.name = args['name']
        if args['views']:
            result.views = args['views']
        if args['likes']:
            result.likes = args['likes']

        db.session.commit()

        return result


    def delete(self, video_id):
        abort_if_video_id_doesnt_exist(video_id)
        del videos[video_id]
        return '', 204


api.add_resource(Video, "/video/<int:video_id>")

if __name__ == "__main__":
    app.run(debug=True)
于 2020-09-23T03:57:27.800 に答える