Yanıtlar:
Django 3.0 itibariyle,
AppConfig.get_model(model_name, require_ready=True)
Django 1.9'dan itibaren yöntem
django.apps.AppConfig.get_model(model_name)
.
- danihp
Django 1.7'den itibaren
django.db.models.loading
, kullanımdan kaldırıldı (1.9'da kaldırılacak), yeni uygulama yükleme sistemi lehine.
- Scott Woodall
Buldum. Burada tanımlanmıştır:
from django.db.models.loading import get_model
Şu şekilde tanımlanır:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. AppConfig nesneleri farklı bir amaca yöneliktir ve çağırmak için bir AppConfig örneği oluşturmanızı gerektirir get_model()
.
django.db.models.loading
edildi Django'ya 1.7'de kaldırıldı ( 1.9 uzaklaştırıldı yeni lehine) uygulama yükleme sistemi .
Django 1.7 belgeleri bunun yerine bize şunu verir:
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
sadece takılıp kalan herkes için (benim yaptığım gibi):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
olması gerektiği gibi tırnak işaretleri kullanılarak listelenmelidir model_name
(yani içe aktarmaya çalışmayın)
get_model
küçük veya büyük 'model_name' kabul eder
Çoğu model "dizesi" "appname.modelname" biçiminde görünür, bu nedenle get_model'de bu varyasyonu kullanmak isteyebilirsiniz.
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
Genellikle bir model haline tür dizeleri döner Django kod parçası biraz daha Bu kompleks dan 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)
Bana göre, bunu çekirdek kodda tek bir işleve bölmek için bu iyi bir durum gibi görünüyor. Ancak, dizelerinizin "Uygulama Modeli" biçiminde olduğunu biliyorsanız, yukarıdaki iki satır çalışacaktır.
your_model = get_model(*your_string.rsplit('.', 1))
. Uygulama etiketi bazen noktalı biçimdedir, ancak model adı her zaman geçerli bir tanımlayıcıdır.
apps.get_model
. "Kısayol olarak, bu yöntem aynı zamanda formdaki tek bir argümanı da kabul eder app_label.model_name
."
Bunu Django 1.7+ ile yapmanın kutsanmış yolu şudur:
import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')
Bu nedenle, tüm çerçeve eğitimlerinin kanonik örneğinde:
import django
entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
Modelinizin hangi uygulamada bulunduğunu bilmiyorsanız, şu şekilde arama yapabilirsiniz:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
Your_model_name'in küçük harf olması gerektiğini unutmayın.
Django'da nerede yapıldığından emin değilim, ama bunu yapabilirsin.
Yansıma yoluyla sınıf adını dizeye eşleme.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
Dizeden bir sınıf elde etmek için django'ya daha az özgü bir yaklaşım:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
ya da importlib'i burada gösterildiği gibi kullanabilirsiniz :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
2020 çözümü:
from django.apps import apps
apps.get_model('app_name', 'Model')
örneğin:
apps.get_model('people', 'Person')