【问题标题】:What is the clean way to integrate another service to django将另一个服务集成到 django 的干净方法是什么
【发布时间】:2020-03-23 20:29:05
【问题描述】:

我有一个 Django 3 应用程序,使用 LDAP 服务类,如下所示:

class LDAPService:
    def init(self, host: str, user: str, password: str, ssl: bool = True):
        ...
    def bind():  # The connection is done here, __init__ just sets values
        ....
    def create_ou(base: str, ou_name: str):
        ....

我应该在哪里(或何时)初始化服务以在视图中使用它?绑定步骤大约需要 2 秒才能应用,我不能对每个请求都执行此操作。如何保持此类的实例共享,而不是每次都完成?我可能有一个使用单例的解决方案,和/或在类似的设置文件中对其进行初始化,但我认为有更好的方法。

我知道在生产中,可能有多个工人,所以有多个实例,但我可以接受。

另一个问题:如何使用来自数据库模型的连接凭据完成上述所有操作(所以不是在 django 启动时,而是在任何时候)

我对 django 生态系统完全陌生,我发现的关于服务层的东西都是关于 django 模型的。我想做与常规服务层中的模型相同的接口,但处理的不是 django 模型。

我认为 LDAP 连接本身不应该存在,只有 CRUD 方法,但我不知道在哪里放置它,以及如何让 django 与之交互。

提前感谢您的建议:)

【问题讨论】:

  • 现在我已将该服务重命名为 _LDAPService,并在文件中将其初始化为 LDAPService,这是我在视图中使用的。
  • 这是一种解决方法,仍然在问问题:)

标签: python django python-3.x design-patterns business-logic


【解决方案1】:

您可以使用memoized factory function

def get_ldap_service() -> LDAPService:
  if not hasattr(get_ldap_service, 'instance'):
    get_ldap_service.instance = LDAPService(**input_from_somewhere)
  return get_ldap_service.instance

这比单例更简洁,并且更容易测试服务类。

此外,将低级连接逻辑发送到另一个类可能是一个更好的设计,比如说

class LDAPConnection:
  def __init__(self, host: str, user: str, password: str, ssl: bool = True):
    ...

然后您的服务层会在运行时将其作为依赖项 (dependency injection)

class LDAPService:
  def __init__(self, connection: LDAPConnection):
    self.connection = connection
  # CRUD operations
  def create_ou(self, base: str, ou_name: str):
    # Do operations via self.connection
    ...

这允许不同的连接暴露相同的接口。

您可以从这两个想法(依赖注入和缓存)构建,以可维护的方式获得更复杂的通用结构。

【讨论】:

  • 您好,感谢您的详细回复。我认为工厂功能是我所缺少的。我还有一个问题 :) 你在哪里初始化 LDAPSercice ?在我看来,我会将服务用作实例类,我应该在哪里做实例? (这可能更像是一个 django 问题)
  • 因此您可以使用工厂方法进行连接或服务本身。我认为在你的情况下,将它用于服务本身并为每个请求调用方法会更简单
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 2021-05-29
  • 2018-10-03
  • 2023-04-03
  • 1970-01-01
  • 2021-07-23
相关资源
最近更新 更多