检索所有包含特定 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 的类定义的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章