[django] Django : 문자열에서 모델을 가져 오시겠습니까?
장고에서는 다음과 같은 관계를 지정할 수 있습니다.
author = ForeignKey('Person')
그리고 내부적으로 문자열 “Person”을 모델로 변환해야합니다 Person
.
이 기능을 수행하는 기능은 어디에 있습니까? 사용하고 싶지만 찾을 수 없습니다.
답변
장고 3.0 기준으로
AppConfig.get_model(model_name, require_ready=True)
Django 1.9부터 방법은
django.apps.AppConfig.get_model(model_name)
입니다.
– danihp
Django 1.7부터는
django.db.models.loading
새로운 애플리케이션 로딩 시스템을 위해 더 이상 사용되지 않습니다 (1.9에서 제거됨).
– 스콧 우달
그것을 발견. 여기에 정의되어 있습니다 :
from django.db.models.loading import get_model
로써 정의 된:
def get_model(self, app_label, model_name, seed_cache=True):
답변
django.db.models.loading
한 장고 1.7에서 사용되지 않는 ( 1.9 제거 하여 새 찬성) 응용 프로그램 로딩 시스템 .
장고 1.7 문서 는 대신 다음을 제공합니다.
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
답변
막힌 사람을 위해 (내가했던 것처럼) :
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
따옴표를 사용하여 나열해야합니다. model_name
(예 : 가져 오지 마십시오)
get_model
소문자 또는 대문자 ‘model_name’을 허용합니다.
답변
대부분의 모델 “문자열”은 “appname.modelname”형식으로 표시되므로 get_model에서이 변형을 사용할 수 있습니다.
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
일반적으로 이러한 문자열을 모델로 변환하는 장고 코드 부분은 조금 더 복잡합니다 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”형식 인 경우 위의 두 라이너가 작동합니다.
답변
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은 소문자 여야합니다.
답변
장고에서 어디에서했는지 확실하지 않지만이 작업을 수행 할 수 있습니다.
리플렉션을 통해 클래스 이름을 문자열에 매핑
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls