【问题标题】:Design patterns for flask API implementationFlask API 实现的设计模式
【发布时间】:2018-01-14 10:44:52
【问题描述】:

我正在使用带有 flask-restplus 和 sqlalchemy 的烧瓶。

我的 rest API 函数如下所示:

@ns.route('/user')
class UsersCollection(Resource):

    @jwt_optional
    @permissions.user_has('admin_view')
    @ns.marshal_list_with(user_details)
    def get(self):
        """
        Returns list of users.
        """

        users = User.query.all()

        return users

我愿意向users 集合添加额外的数据,这些数据应该由 API 返回。其中一些数据可能存储在其他数据库表中,而另一些则存储在内存中。

我通常做的是这样的:

@ns.route('/user')
class UsersCollection(Resource):

    @jwt_optional
    @permissions.user_has('admin_view')
    @ns.marshal_list_with(user_details)
    def get(self):
        """
        Returns list of users.
        """

        users = User.query.all()

        # Add additional data
        for user in users:
          user.activity = UserActivity.query ...  # from DB 
          user.online_status = "Active" # Taken somewhere from memory

        return users

显然,我不喜欢这种将数据动态添加到 User 对象的方法。但是实现它的最佳设计模式是什么?

【问题讨论】:

  • 好吧,我唯一想到的就是增加一个包含用户、他的活动和他的状态的类。
  • 我实际上是在阅读有关使用棉花糖和定义另一个类的信息,但没有太多经验,我不确定这是正确的选择......
  • 抱歉回答晚了,我很忙,我没有太多使用 Python 工作的经验,但如果我在 kotlin 或 java 中遇到类似问题,我肯定会再上一堂课。 Python 能够为您现在正在使用的实例添加功能,我不确定这是否被认为是最佳实践,对我来说这有点奇怪,但如果您的项目很小,请保持这种方式,它简单易懂,如果您必须添加更多功能,请创建将所有需要的数据包装在一起的类。
  • 另一个选择是继承,但我更喜欢组合,因为它不是紧密耦合的,您可以轻松添加或删除内容,而无需过多更改代码。

标签: python rest flask sqlalchemy flask-restplus


【解决方案1】:

关于设计模式,我推荐一种 DAO 和服务方法,这里有一篇很好的简短文章: https://levelup.gitconnected.com/structuring-a-large-production-flask-application-7a0066a65447

关于模型用户/活动关系,我假设您有一个映射的活动模型。如果这是一对一的关系,在用户模型中为 FK 字段创建一个 activityId 字段和一个 activity 关系,您的 ORM(我假设 SQLAlchemy)将user.activity 被访问时检索。

class Activity(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    descrption = db.Column(db.String(255))

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    activity = db.relationship(Activity)
    activityId = db.Column(db.Integer, db.ForeignKey(Activity.id))

如果你有一个多对多关系,你必须创建一个名为 ActivityUser 的第三个类来映射关系

class ActivityUser(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    activity = db.relationship(Activity, lazy=True)
    user = db.relationship(User, lazy=True)
    activityId = db.Column(db.ForeignKey(Activity))
    userId = db.Column(db.ForeignKey(User))

您可以像这样检索用户活动(再次假设您使用 SQLAlchemy):

ActivityUser.query.filter(ActivityUser.userId == user.id).all()

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多