在Django中,你可以指定喜歡的關係:Django:從字符串獲取模型?
author = ForeignKey('Person')
,然後在內部它有字符串「人」轉換成模型Person
。
這是幹什麼的功能?我想用它,但我找不到它。
在Django中,你可以指定喜歡的關係:Django:從字符串獲取模型?
author = ForeignKey('Person')
,然後在內部它有字符串「人」轉換成模型Person
。
這是幹什麼的功能?我想用它,但我找不到它。
作爲Django的1.9的方法是
django.apps.AppConfig.get_model(model_name)
。
- danihp
作爲Django的1.7的
django.db.models.loading
被棄用,取而代之的新的應用程序加載系統的(在1.9中刪除)。
- Scott Woodall
發現了它。它的定義如下:
from django.db.models.loading import get_model
定義爲:
def get_model(self, app_label, model_name, seed_cache=True):
我不確定它在Django中的位置,但可以這樣做。
通過反射將類名映射到字符串。
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
是否clls .__類__.__ name__或只是clls .__ name__? – 2017-07-25 12:08:22
大多數模型 「串」 出現的形式是 「appname.modelname」 所以你可能想使用get_model這種變化
from django.db.models.loading import get_model
your_model = get_model (*your_string.split('.',1))
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)
對我來說,這似乎是一個很好的例子,將它分解爲核心代碼中的單個函數。但是,如果你知道你的字符串是「App.Model」格式,上面的兩個班輪將工作。
只是任何人都陷入(像我一樣):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
應使用引號上市,也應model_name
(即不要試圖將其導入)
get_model
接受小寫或大寫「模型名稱」
作爲Django的1.7的django.db.models.loading
is deprecated贊成新的應用程序加載系統(將在1.9移除)。該1.7 docs give us的,而不是以下:每tttthomasssss評論
$ 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'>
>>>
編輯。
在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.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
請記住,your_model_name必須是小寫。
這裏是一個不太具體的Django的方法來從字符串獲取類:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
,或者您可以使用導入庫,如圖here:
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
此解決方案在Django 1.7中已棄用,請參閱此解決方案的其他答案:http://stackoverflow.com/a/26126935/155987 – 2015-06-30 22:26:22
嗨@mpen,我建議您更新您的答案。 [在django 1.9上get_model在AppConfig上定義](https://docs.djangoproject.com/es/1.9/ref/applications/#django.apps.AppConfig.get_model):`from django.apps import AppConfig` – danihp 2016-04-20 14:18:03
@danihp謝謝,補充說明。 – mpen 2016-04-20 21:24:53