【问题标题】:Django: app level variablesDjango:应用程序级变量
【发布时间】:2017-01-22 06:48:27
【问题描述】:

我创建了一个 Django-rest-framework 应用程序。它公开了一些在 MySQL DB 中执行一些 get/set 操作的 API。

我需要向另一台服务器发出 HTTP 请求,并将此响应与通常的响应一起搭载。我正在尝试使用自制的 HTTP 连接池来发出 HTTP 请求,而不是在每个请求上都建立新的连接。

保存这个应用级 HTTP 连接池对象的最合适的位置是什么?

我已经四处寻找它,并且有多种解决方案,每种都有一些缺点。以下是一些:

  1. 在 diff 文件中创建一个池的单例类,但这不是一个很好的 Pythonic 做事方式。关于为什么不使用单例设计模式存在各种讨论。

    另外,我不知道汇集一个pooler会有多聪明? (:P)

  2. 将其保存在应用程序目录的 init.py 中。问题如下:
    • 它应该只包含导入和与之相关的东西。
    • 很难对代码进行单元测试,因为导入会在模拟之前发生,并且实际上会尝试访问 API。
  3. 使用会话,但我想如果它是特定于用户会话的东西,比如用户特定的数字等,那会更有意义

    此外,对象需要可序列化。不知道HTTP连接池是怎么序列化的。

  4. 在 views.py 中保持全局性,但也不鼓励这样做。

存储此类应用程序/全局级别变量的最佳位置是什么?

【问题讨论】:

  • 你有没有找到更好的解决方案来实现这个?

标签: python django django-rest-framework global-variables


【解决方案1】:

这个帖子有点旧,但仍然可以用谷歌搜索。一般来说,如果你希望一个组件可以在你的 Django 项目中的多个应用程序中访问,你可以将它放在 general 或 core 应用程序中作为 Util 或其他。

就可重用性和特定应用而言,您可以使用具有缓存机制的工厂,例如:

class ConnectionPool:
    pass


@dataclass
class ConnectionPoolFactory:
    connection_pool_cache: dict[str: ConnectionPool] = field(default_factory=dict)

    def get_connection(self, app_name: str) -> ConnectionPool:
        if self.connection_pool_cache.get(app_name, None) is None:
            self.connection_pool_cache[app_name] = ConnectionPool()
        return self.connection_pool_cache[app_name]

【讨论】:

    【解决方案2】:

    一种可能的解决方案是实现自定义 Django 中间件,如 https://docs.djangoproject.com/ja/1.9/topics/http/middleware/ 中所述。

    您可以在中间件的 __init__ 方法中初始化 HTTP 连接池,该方法仅在第一次请求时调用一次。然后,在 process_request 期间启动 HTTP 请求,并在 process_response 检查它是否已完成(或等待它)并将该响应附加到内部请求。

    【讨论】:

    • 我提到的所有方法呢?您对此有何看法?
    • 我同意您对您提出的解决方案的看法。此外,Django 的初始化可能很难跟踪,因为我更喜欢自定义中间件的初始化。
    • 点击 API 是一项业务需求,我认为,并且只有 1 个或多个公开的 API 需要。不适合所有人。此要求可以更改/更改 acc。为将来的需要。如果我错了,请纠正我,但我认为你的方法会更有用,我必须对所有请求和所有 API 提出请求。对于这个特殊的需求,如果我可以在views.py中获取池对象,我想我可以在views.py中提出请求
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    相关资源
    最近更新 更多