Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何设置三层web应用程序项目_Python_Design Patterns_Model View Controller_Orm_Sqlalchemy - Fatal编程技术网

Python 如何设置三层web应用程序项目

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项目,我们必须为其设置一个结构。关于如何设置,有两种有效的意见,在项目真正开始之前,我们想确定其中一种意见。 如果你们中的任何人能给我们一些见

编辑:

我添加了[MVC]和[design patterns]标签来扩大这个问题的受众范围,因为它更多的是一个通用编程问题,而不是直接与Python或SQLalchemy有关的问题。它适用于所有具有业务逻辑和ORM的应用程序。
基本问题是,是将业务逻辑保留在单独的模块中,还是将其添加到我们的ORM提供的类中更好:

我们有一个flask/sqlalchemy项目,我们必须为其设置一个结构。关于如何设置,有两种有效的意见,在项目真正开始之前,我们想确定其中一种意见。
如果你们中的任何人能给我们一些见解,说明这两种方法中哪一种更有意义,为什么更有意义,以及它们的优点/缺点,我们将不胜感激


我的示例是一封需要批量发送和/或显示给单个用户的HTML信函。信函可以包含显示发票和/或收件人的物品列表的部分


方法1:
将代码分为3层-第一层:web界面,第二层:信件处理,第三层:ORM(sqlalchemy)中的模型。
网站将在第二层的类中调用服务器端方法,第二层将循环通过需要获取此信函的用户,它将具有生成HTML的内部方法,并使用当前用户的信息替换信函中的一些通用字段。它还有内部方法来生成发票或要放置在信件中的物品列表

在这种方法中,第三层仅用于从数据库中获取数据,可能还有一些与数据库相关的逻辑,比如从用户的名字和姓氏生成全名。第二层执行大部分工作

方法2: 将代码拆分为相同的三层,但只在第二层的用户集合中执行循环

生成HTML、发票和文章列表的方法都作为方法添加到ORM提供的tier 3中的模型定义中。第二层执行循环,但实际功能包含在第三层的模型类中

我们得出结论,这两种方法都可行,并且都有利弊:

方法1:

  • 将业务逻辑与数据库访问完全分离
  • 防止导入ORM模型也会导入许多我们可能不需要的方法/功能,同时使模型类的代码更加紧凑
  • 在模拟ORM模型进行测试时可能更容易使用
方法2:

  • 似乎与Django在Python中的工作方式一致
  • 允许对方法的简单访问:当模型实例存在时,任何函数 可以立即调用。(在我的示例中:当我有一个字母实例可用时,我可以直接调用该实例上的一个方法,该方法生成该字母的HTML)
  • 您可以传递实例,手头有所有适当的方法
通常情况下,您会使用这种模式来处理此类内容,但python中的大多数web框架都放弃了“控制器”部分,因为他们认为它是一个不必要的组件。在我的成长过程中,我意识到,这在某种程度上是正确的:没有它我可以活下去。这将给您留下两个层:视图和模型

问题是现在将业务逻辑放在哪里。从实际意义上讲,有两种方法可以做到这一点,至少有两种方法让我面临着把逻辑放在哪里的问题:

  • 创建处理逻辑的特殊内部视图方法,这些逻辑可能在多个视图中需要,例如
    \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,因此在模板中定义会很难看。