Django的:从string获取模型?

在Django中,您可以指定如下关系:

author = ForeignKey('Person') 

然后在内部它必须将string“Person”转换成模型Person

function在哪里呢? 我想用它,但我找不到它。

从Django 1.9开始,方法是django.apps.AppConfig.get_model(model_name)
– danihp


从Django 1.7开始, django.db.models.loading已被弃用(将在1.9中被删除),以支持新的应用程序加载系统。
– 斯科特伍德


find了。 在这里定义:

 from django.db.models.loading import get_model 

定义为:

 def get_model(self, app_label, model_name, seed_cache=True): 

从Django 1.7开始, django.db.models.loading 已被弃用 (将在1.9中被删除),以支持新的应用程序加载系统。 1.7文档给我们下面的代替:

 $ python manage.py shell Python 2.7.6 (default, Mar 5 2014, 10:59:47) >>> from django.apps import apps >>> User = apps.get_model(app_label='auth', model_name='User') >>> print User <class 'django.contrib.auth.models.User'> >>> 

编辑每tttthomasssss评论。

大多数模型“string”以“appname.modelname”的forms出现,因此您可能想要在get_model上使用此变体

 from django.db.models.loading import get_model your_model = get_model ( *your_string.split('.',1) ) 

通常把这样的string变成模型的django代码的一部分更复杂一点这从django/db/models/fields/related.py

  try: app_label, model_name = relation.split(".") except ValueError: # If we can't split, assume a model in current app app_label = cls._meta.app_label model_name = relation except AttributeError: # If it doesn't have a split it's actually a model class app_label = relation._meta.app_label model_name = relation._meta.object_name # Try to look up the related model, and if it's already loaded resolve the # string right away. If get_model returns None, it means that the related # model isn't loaded yet, so we need to pend the relation until the class # is prepared. model = get_model(app_label, model_name, seed_cache=False, only_installed=False) 

对我来说,这似乎是将其分解成核心代码中的单个函数的好例子。 但是,如果您知道您的string是“App.Model”格式,则上面的两个class轮将工作。

在Django 1.7+中这样做的有福之道是:

 import django model_cls = django.apps.apps.get_model('app_name', 'model_name') 

所以,在所有框架教程的规范例子中:

 import django entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive 

只为任何人卡住(像我一样):

 from django.apps import apps model = apps.get_model('app_name', 'model_name') 

app_name应该用引号列出,就像model_name (即不要试图导入它)

get_model接受小写或大写'model_name'

我不确定它在Django中做了什么,但是你可以做到这一点。

通过reflection将类名映射到string。

 classes = [Person,Child,Parent] def find_class(name): for clls in classes: if clls.__class__.__name__ == name: return clls 

如果您不知道模型存在于哪个应用程序中,则可以通过以下方式进行search:

 from django.contrib.contenttypes.models import ContentType ct = ContentType.objects.get(model='your_model_name') model = ct.model_class() 

请记住,your_model_name必须是小写。

这是一个较lessDjango特定的方法来从string中获得一个类:

 mymodels = ['ModelA', 'ModelB'] model_list = __import__('<appname>.models', fromlist=mymodels) model_a = getattr(model_list, 'ModelA') 

或者你可以使用importlib,如下所示:

 import importlib myapp_models = importlib.import_module('<appname>.models') model_a = getattr(myapp_models, 'ModelA')