如何获取Django对象的模型名称或内容类型?

61

假设我在保存代码中,如何获取模型的名称或对象的内容类型,并使用它?

from django.db import models

class Foo(models.Model):
    ...
    def save(self):
        I am here....I want to obtain the model_name or the content type of the object
这段代码可以执行,但是我必须知道model_name是什么:
import django.db.models
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get(model=model_name)
model = content_type.model_class()
3个回答

111

您可以通过以下方式从对象中获取模型名称:

self.__class__.__name__

如果你偏爱内容类型,你应该可以这样获取:

from django.contrib.contenttypes.models import ContentType
ContentType.objects.get_for_model(self)

如果您有一个数据库浏览器工具,您可以看到创建了一个django_content_type。它包含一些字段,如名称、应用程序标签和模型。我需要从我所在的类中获取该模型信息。 - Seitaridis
1
模型字段是小写字符串,它派生自类名。 - Seitaridis
1
然后像这样做:'ct = ContentType.objects.get_for_model(self)',接着是'return ct.app_label'或者你需要的任何ContentType属性。 - gravelpot
1
或者只需将类名转换为小写以获取内容类型,任选其一... 'print self.class.name.lower()' - gravelpot
谢谢。ContentType.objects.get_for_model(self)解决了问题。 - Seitaridis
3
通过“ContentType”的解决方案需要进行额外的SQL请求。 - tobltobs

11

方法get_for_model有一些花哨的东西,但在某些情况下最好不要使用那些花哨的东西。特别是,假设你想过滤与ContentType链接的模型,可能通过通用外键?? 这里的问题是,在以下代码中应该使用什么model_name

content_type = ContentType.objects.get(model=model_name)

使用Foo._meta.model_name,或者如果您有一个Foo对象,则obj._meta.model_name就是您要查找的内容。然后,您可以执行以下操作:

Bar.objects.filter(content_type__model=Foo._meta.model_name)

这是一种高效的方法,用于过滤Bar表以返回链接到Foo内容类型的对象,该链接通过名为content_type的字段实现。


4

使用gravelpot的答案,直接回答OP的问题:

我们可以通过instance.__class__获取对象的类,并将其传递给get_for_model函数:

from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(instance.__class__)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接