django:从该模型的实例获取模型的最佳实践方法


69

my_instance是榜样MyModel
我正在寻找一种好方法:

my_model = get_model_for_instance(my_instance)

我还没有找到任何真正直接的方法来做到这一点。到目前为止,我已经提出了:

from django.db.models import get_model

my_model = get_model(my_instance._meta.app_label, my_instance.__class__.__name__)

这可以接受吗?它甚至是肯定可行的最佳实践方法吗?
还有_meta.object_name似乎提供与相同的东西__class__.__name__。可以?是好是坏?如果是这样,为什么?

另外,如果应用程序标签在项目范围内多次出现,例如如何从“ django.contrib.auth”获得“ auth”,并且还存在“ myproject.auth”,我怎么知道我得到的模型正确?
这样的情况get_model会变得不可靠吗?

感谢您的任何提示/提示和经验分享!


3
__class__绝对必须是该实例的类。没有任何歧义。这就是Python的工作方式。你在问什么?
S.Lott

好吧,我在这里有一些理解上的局限性。对我来说,模棱两可的是,可能存在不止一个应用程序标签/类名组合,它们生活在不同的模块中。但是,get_model不接收该模块作为输入。那么它将提供哪种模型?另一件事是我不了解object_name有什么用,因为它返回的字符串与字符串相同__class__.__name__,并且有多少人选择这两个字符串中的哪一个在内部get_model或其他地方使用。谢谢!
Geradeausanwalt,2010年

Answers:


113
my_model = type(my_instance)

为了证明这一点,您可以创建另一个实例:

my_new_instance = type(my_instance)()

这就是为什么没有直接方法的原因,因为python对象已经具有此功能。

更新...

我喜欢marcinn使用的响应type(x)。这与原始答案(x.__class__)相同,但是与使用魔术属性相比,我更喜欢使用函数。以这种方式,我更喜欢使用vars(x)to x.__dict__len(x)tox.__len__等等。

更新了2 ...

对于延迟的实例(@Cerin在注释中提到),您可以通过访问原始类instance._meta.proxy_for_model


3
这不适用于延迟的实例或使用进行查询的实例only()
塞林2014年

非常感谢您的“更新2”。我花了很长时间寻找如何访问原始课程。
andreibosco


9

至少对于Django 1.11,这应该有效(也适用于延迟实例):

def get_model_for_instance(instance):
    return instance._meta.model

来源在这里


2
尽管此方法有效,但不幸的是,我之前曾使用过此方法,就“最佳实践”而言,_meta.model它不在_meta API中,也不应该使用,它type()是更好的并且是Python语言。
安迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.