[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