Django: Get model from string?
在Django中,可以指定以下关系:
1 | author = ForeignKey('Person') |
然后在内部,它必须将字符串"person"转换为模型
做这个的函数在哪里?我想用,但找不到。
As of Django 1.9 the method is
django.apps.AppConfig.get_model(model_name) .
-- danihp
As of Django 1.7 the
django.db.models.loading is deprecated (to be removed in 1.9) in favor of the the new application loading system.
-- Scott Woodall
找到它了。定义如下:
1 | from django.db.models.loading import get_model |
定义为:
1 | def get_model(self, app_label, model_name, seed_cache=True): |
从Django 1.7开始,为了支持新的应用程序加载系统,不推荐使用
1 2 3 4 5 6 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'> >>> |
根据tttthomassss注释编辑。
对于任何一个被卡住的人(就像我一样):
1 2 3 | from django.apps import apps model = apps.get_model('app_name', 'model_name') |
大多数模型"字符串"以"appname.modelname"的形式出现,因此您可能希望在get_模型上使用此变体。
1 2 3 | from django.db.models.loading import get_model your_model = get_model ( *your_string.split('.',1) ) |
django代码中通常将这些字符串转换为模型的部分比
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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) |
在我看来,这是一个很好的例子,可以将其分解为核心代码中的单个函数。但是,如果您知道您的字符串是"app.model"格式,那么上面的两个行程序就可以工作了。
在Django 1.7+中这样做的幸运方式是:
1 2 | import django model_cls = django.apps.apps.get_model('app_name', 'model_name') |
因此,在所有框架教程的规范示例中:
1 2 | import django entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive |
如果您不知道您的模型存在于哪个应用程序中,您可以通过以下方式进行搜索:
1 2 3 | from django.contrib.contenttypes.models import ContentType ct = ContentType.objects.get(model='your_model_name') model = ct.model_class() |
请记住,您的型号名称必须是小写。
我不知道在姜戈的什么地方,但你可以这样做。
通过反射将类名映射到字符串。
1 2 3 4 5 | classes = [Person,Child,Parent] def find_class(name): for clls in classes: if clls.__class__.__name__ == name: return clls |
下面是从字符串中获取类的一种不太特定于django的方法:
1 2 3 | mymodels = ['ModelA', 'ModelB'] model_list = __import__('.models', fromlist=mymodels) model_a = getattr(model_list, 'ModelA') |
或者可以使用importlib,如下所示:
1 2 3 | import importlib myapp_models = importlib.import_module('.models') model_a = getattr(myapp_models, 'ModelA') |