检索所有包含特定 mixin 的类定义的正确方法是啥?

Posted

技术标签:

【中文标题】检索所有包含特定 mixin 的类定义的正确方法是啥?【英文标题】:What is the proper way to retrieve all class definitions that contain a specific mixin?检索所有包含特定 mixin 的类定义的正确方法是什么? 【发布时间】:2020-09-16 20:51:28 【问题描述】:

我正在开发一个 django 应用程序,我想创建一个始终应用于模型定义的 mixin。 mixin 添加的功能对于这个问题并不重要。

但是,我需要能够检索从该 mixin 继承的所有类定义的列表。这些类可以在 django 项目的不同应用中。

目前我找到的可能答案是:

How to find all the subclasses of a class given its name?

How to auto register a class when it's defined

我主要想知道实现这一目标的最佳方法是什么。

【问题讨论】:

您想在代码中执行此操作,例如您的应用程序需要这样做,或者您想检查这些类,如果以后我会做一个 git grep MixinName 基本上没有办法以编程方式做到这一点,因为可能有无数其他模块导入和使用该 mixin,而您的程序无法真正发现它们.要“手动”执行此操作,好的 IDE 会有所帮助。 在这种情况下,mixin 只会应用于实际的 django 模型定义,我编辑了问题以反映这一点。这会影响类的可发现性吗? 那么您是否尝试了链接中的__subclasses__?或者通过定义__init_subclass__? 我确实尝试过__subclasses__,但是它只能引用在使用它的代码部分中实际导入的模型。因此,虽然在大多数情况下就足够了,但在某些情况下,项目中的某些子类被跳过了。 【参考方案1】:

通常,获取继承特定类的所有类的列表的方法是使用元类注册这些类(如您所链接的问题之一中所述)。然而,Django 模型使用它们自己的元类来实现它们自动执行的许多操作。我不建议在混合中添加另一个元类 - 这里可能会出错!

然而,幸运的是,django 有一个名为 content-types framework 的东西,它本质上是一个特定项目中所有模型的注册表。

要获得所有模型的列表,您可以这样做:

from django.contrib.contenttypes.models import ContentType

content_types = ContentType.objects.all()

这不会得到实际的模型,而是ContentType 实例的查询集。然后从中获取模型类,您可以这样做

models = [x.model_class() for x in content_types]

所以我们现在有了一个模型列表。然后我们可以将列表过滤到那些继承你的 mixin 的模型:

models_with_mixin = [x for x in models if issubclass(x, MyMixin)]

我们可以将以上所有内容简化为以下内容:

from django.contrib.contenttypes.models import ContentType

models_with_mixin = [
    x.model_class()
    for x in ContentType.objects.all()
    if issubclass(x.model_class(), MyMixin)
]

【讨论】:

这个答案为我解决了这个问题。我已经熟悉 ContentType,但我没有意识到它可以这样使用。然而,代码 sn-ps 有 1 个错误。 issubclass 的参数应该是相反的:issubclass(x, MyMixin) 啊,抱歉打错了。我会纠正的。很高兴帮助:)

以上是关于检索所有包含特定 mixin 的类定义的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

只包含 mixin 的类的名称是啥?

检索附加了特定帐户的所有联系人

在 Polymer.dart 中定义全局过滤器/变压器

Sass混合的使用

获取包含模块的类列表

Sass混合的使用