如何获得Django模型的应用程序来自?

e-s*_*tis 29 django model

我有一个具有通用关系的模型:

TrackedItem --- genericrelation ---> any model
Run Code Online (Sandbox Code Playgroud)

我希望能够从初始模型中获得跟踪项目.

我应该可以在任何模型上进行,而无需修改它.

为此,我需要获取内容类型和对象ID.获取对象id很简单,因为我有模型实例,但获取内容类型不是:ContentType.object.filter需要模型(只是content_object.__class__.__name__)和app_label.

我不知道如何以可靠的方式获得模型所在的应用程序.

我现在这样做app = content_object.__module__.split(".")[0],但它不适用于django contrib应用程序.

Wog*_*gan 90

app_label可作为对属性_meta的任何模型的属性.

from django.contrib.auth.models import User
print User._meta.app_label
# The object name is also available
print User._meta.object_name
Run Code Online (Sandbox Code Playgroud)

  • @AddisonKlinke 也许,但公平地说,他的答案需要导入和数据库命中 (7认同)
  • `_meta` 不是私有的,它带有前缀以避免与用户创建的模型字段发生冲突。它记录在这里:https://docs.djangoproject.com/en/3.2/ref/models/meta/ (4认同)

Dan*_*man 33

您不需要获取应用程序或模型来获取内容类型 - 有一个方便的方法可以做到这一点:

from django.contrib.contenttypes.models import ContentType

ContentType.objects.get_for_model(myobject)
Run Code Online (Sandbox Code Playgroud)

尽管名称,它适用于模型类和实例.

  • 是吗?这不是数据库吗? (8认同)
  • 导入是:从django.contrib.contenttypes.models导入ContentType (4认同)
  • 这是比使用_meta更好的解决方案. (3认同)
  • @meshy 是的,但是 django ContentType 在其管理器上使用缓存,因此每个模型只查询一次。 (2认同)
  • 使用“.app_label”从“get_for_model()”方法返回的 ContentType 对象中获取应用程序字符串。我在下面添加了一个例子。希望对您有所帮助。 (2认同)

Dos*_*Dos 6

您可以使用内置的ContentType类从对象中同时获取app_label和获取:model

from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User

user_obj = User.objects.create()
obj_content_type = ContentType.objects.get_for_model(user_obj)

print(obj_content_type.app_label)
# u'auth'
print(obj_content_type.model)
# u'user'
Run Code Online (Sandbox Code Playgroud)

这是使用_meta为私人目的定义的属性时更好的方法。