Django - 防止自动相关表获取

Mar*_*ast 5 django

出于测试目的,如何防止 Django 在初始查询期间自动获取 select_lated() 调用中未指定的相关表?

我有一个大型应用程序,在每个原始查询期间,我大量使用 select_lated() 引入相关模型数据。所有 select_lated() 调用都用于指定特定的相关模型,而不是依赖于默认模型,例如 select_lated('foo', 'bar', 'foo__bar')

随着应用程序的增长,select_lated 调用还没有完全跟上,留下了许多 Django 愉快而友好地运行到数据库以获取相关模型行的场景。这显着增加了数据库命中的数量,这显然是我不希望的。

通过检查使用 django.db.connection.queries 集合生成的查询,我已经成功地跟踪了这些问题,但有些问题仍未解决。

我尝试在 django 代码中找到合适的补丁位置,以在这种情况下引发异常,从而使跟踪变得更容易,但往往会迷失在代码中。

谢谢。

Mar*_*ast 1

经过更多挖掘后,我在代码中找到了执行此操作的位置。

有问题的文件是 django/db/models/fields/lated.py

您需要在此文件中插入两行。

找到类“SingleRelatedObjectDescriptor”。您需要按如下方式更改函数 __get__():

def __get__(self, instance, instance_type=None):
    if instance is None:
        return self
    try:
        return getattr(instance, self.cache_name)
    except AttributeError:
        raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.related.get_accessor_name()))
        # leave the old code here for when you revert!
Run Code Online (Sandbox Code Playgroud)

同样,在代码的“ReverseSingleRelatedObjectDescriptor”类中,您再次需要将 __get__() 更改为:

def __get__(self, instance, instance_type=None):
    if instance is None:
        return self

    cache_name = self.field.get_cache_name()
    try:
        return getattr(instance, cache_name)
    except AttributeError:
        raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.field.name))
        # BEWARE: % parameters are different to previous class
        # leave old code here for when you revert
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您会发现 Django 每次执行自动数据库查找时都会引发异常。当您第一次开始时,这非常烦人,但它将帮助您跟踪那些讨厌的数据库查找。显然,当您找到所有这些后,最好将数据库代码恢复到正常状态。我只建议在调试/性能调查阶段使用它,而不是在实时生产代码中使用它!