Python 如何设置三层web应用程序项目
编辑: 我添加了[MVC]和[design patterns]标签来扩大这个问题的受众范围,因为它更多的是一个通用编程问题,而不是直接与Python或SQLalchemy有关的问题。它适用于所有具有业务逻辑和ORM的应用程序。Python 如何设置三层web应用程序项目,python,design-patterns,model-view-controller,orm,sqlalchemy,Python,Design Patterns,Model View Controller,Orm,Sqlalchemy,编辑: 我添加了[MVC]和[design patterns]标签来扩大这个问题的受众范围,因为它更多的是一个通用编程问题,而不是直接与Python或SQLalchemy有关的问题。它适用于所有具有业务逻辑和ORM的应用程序。 基本问题是,是将业务逻辑保留在单独的模块中,还是将其添加到我们的ORM提供的类中更好: 我们有一个flask/sqlalchemy项目,我们必须为其设置一个结构。关于如何设置,有两种有效的意见,在项目真正开始之前,我们想确定其中一种意见。 如果你们中的任何人能给我们一些见
基本问题是,是将业务逻辑保留在单独的模块中,还是将其添加到我们的ORM提供的类中更好: 我们有一个flask/sqlalchemy项目,我们必须为其设置一个结构。关于如何设置,有两种有效的意见,在项目真正开始之前,我们想确定其中一种意见。
如果你们中的任何人能给我们一些见解,说明这两种方法中哪一种更有意义,为什么更有意义,以及它们的优点/缺点,我们将不胜感激
我的示例是一封需要批量发送和/或显示给单个用户的HTML信函。信函可以包含显示发票和/或收件人的物品列表的部分
方法1:
将代码分为3层-第一层:web界面,第二层:信件处理,第三层:ORM(sqlalchemy)中的模型。
网站将在第二层的类中调用服务器端方法,第二层将循环通过需要获取此信函的用户,它将具有生成HTML的内部方法,并使用当前用户的信息替换信函中的一些通用字段。它还有内部方法来生成发票或要放置在信件中的物品列表 在这种方法中,第三层仅用于从数据库中获取数据,可能还有一些与数据库相关的逻辑,比如从用户的名字和姓氏生成全名。第二层执行大部分工作 方法2: 将代码拆分为相同的三层,但只在第二层的用户集合中执行循环 生成HTML、发票和文章列表的方法都作为方法添加到ORM提供的tier 3中的模型定义中。第二层执行循环,但实际功能包含在第三层的模型类中 我们得出结论,这两种方法都可行,并且都有利弊: 方法1:
- 将业务逻辑与数据库访问完全分离
- 防止导入ORM模型也会导入许多我们可能不需要的方法/功能,同时使模型类的代码更加紧凑
- 在模拟ORM模型进行测试时可能更容易使用
- 似乎与Django在Python中的工作方式一致
- 允许对方法的简单访问:当模型实例存在时,任何函数 可以立即调用。(在我的示例中:当我有一个字母实例可用时,我可以直接调用该实例上的一个方法,该方法生成该字母的HTML)
- 您可以传递实例,手头有所有适当的方法
- 创建处理逻辑的特殊内部视图方法,这些逻辑可能在多个视图中需要,例如
\u process\u list\u data
- 创建与模型相关但不直接绑定到相应模型模块内单个实例的函数,例如
check\u login
\u process\u list\u data
存在于视图类中(按目的对方法进行分组),但也可以是模块中的普通函数。它接收一些参数,例如数据列表,并以某种方式对其进行格式化(例如,它可以添加额外的视图参数,以便模板具有较少的逻辑)。然后,它将数据集返回给原始视图函数,该函数可以传递数据集,也可以进一步处理数据集
第二个用于大多数其他逻辑,我喜欢将其排除在直接查看代码之外,以便于测试。我的check\u login
示例就是这样做的:它是一个与显示输出没有直接联系的函数,因为它的目的是检查用户登录凭据,并决定返回用户或报告登录失败(通过抛出异常,返回False
或返回None
)。但是,该功能也没有直接绑定到模型,因此它不能存在于ORM类中(对于用户
对象,它可以是静态方法
)。相反,它只是模块中的一个函数(请记住,这是Python,您应该使用可用的最简单方法,函数就在那里)
总而言之:在视图中显示逻辑,在模型中显示所有其他内容,因为大多数逻辑以某种方式与特定模型相关联。如果不是,就为这种逻辑创建一个新的模块或包。这可能是一个单独的模块,甚至是一个包。例如,我经常为helper函数创建一个util
模块/包,该模块/包不直接与任何视图、模型或其他对象绑定,例如,一个用于格式化从模板调用的日期的函数,但它包含太多python,因此在模板中定义会很难看。