【问题标题】:Decoupling Django signals from classes that touch the DB将 Django 信号与接触数据库的类解耦
【发布时间】:2018-05-15 10:09:55
【问题描述】:

我有一个发送信号的应用程序,我们称之为signal_x。在另一个应用程序中,为signal_x 定义了一个@receiver,在它的apps.pyready() 函数中是包含导入接收器的文件。

@receiver 函数有一个问题。它依赖于一个对象,我们称之为object_y,它在它的构造函数中依赖于数据库。使用从数据库中提取的值,构建了一些重物。这些重对象必须在内存中,以便进行非常快速的计算,因此它们不能延迟加载,因为第一次使用它们会花费很长时间。 self.location_ids 也不能延迟加载,因为它被两个 compute_heavy_... 函数使用。

一切正常,直到我们删除数据库,再次创建它并运行 ma​​nage.py makemigrations。现在 ma​​kemigrations 将失败,因为 Django 首先运行 django.setup(),它运行每个应用程序的 ready() 函数。当它通过导入到达ready() 函数时,它将按预期导入文件并尝试创建object_y。但是object_y 需要尚不存在的模型,因此会出现错误。我怎样才能优雅地解决/规避这个问题?

class Recommender:
    def __init__(self):
        self.location_ids = self.get_location_ids()
        self.heavy_object1 = self.compute_heavy_object1(location_ids)
        self.heavy_object2 = self.compute_heavy_object2(..., location_ids)

    def get_location_ids():
        locations = LocationNode.objects.filter(level=1, parent_id=1)
        return [location.id for location in locations]

... meantime in another file

object_y = Recommender()

@receiver(signal_x, dispatch_uid="update_state")
def recompute(sender, **kwargs):
    client_id = kwargs['client_id']
    # prepare some things
    heavy_recompute(object_y, client_id)

【问题讨论】:

  • 你的例子不是很清楚。什么是HeavyObject? object_y 用在哪里?
  • 很抱歉打错字了,我现在已经修好了线路。所以 object_y 是 Recommender 对象,heavy_recompute 需要 object_y。 Recommender 对象不是 Django 模型,但它具有派生自 Django 模型的属性(在示例中为 self.location_ids)。

标签: django django-models django-signals


【解决方案1】:

这是一个常见的用例。由于您没有提供这么多代码,因此很难给您一个非常准确的答案,但是,请考虑一下:

  • AppConfig.ready() 函数中,您应该始终使用self.get_model() 来检索对另一个应用程序中定义的模型的引用。如果require_ready=True(默认值),这将确保应用程序注册表是最新的。在AppConfig 方法之外,您可以使用apps.get_model()
  • 不要在模块级别创建模型实例 (object_y = HeavyObject())。注意:我不知道HeavyObject 是否是 Django 模型。但一般情况下,你可以默认声明object_y = None,稍后再初始化变量

【讨论】:

  • 非常感谢您的提示。我不知道 get_model() 函数。同时,我很抱歉在代码示例中写了几个错别字。现在一切都解决了,应该更清楚了。
猜你喜欢
  • 2011-09-19
  • 2018-07-21
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多