W Django możesz określić relacje takie jak:
author = ForeignKey('Person')
Następnie wewnętrznie musi przekształcić łańcuch „Osoba” w model Person
.
Gdzie jest funkcja, która to robi? Chcę go użyć, ale nie mogę go znaleźć.
django
django-models
mpen
źródło
źródło
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. Obiekty AppConfig są przeznaczone do innego celu i wymagają utworzenia wystąpienia AppConfig w celu wywołaniaget_model()
.django.db.models.loading
został przestarzały w Django 1.7 ( usunięty w 1.9 ) na rzecz nowego systemu ładowania aplikacji .Zamiast tego dokumentacja Django 1.7 zawiera następujące informacje:
>>> from django.apps import apps >>> User = apps.get_model(app_label='auth', model_name='User') >>> print(User) <class 'django.contrib.auth.models.User'>
źródło
tylko dla każdego, kto utknął (tak jak ja):
from django.apps import apps model = apps.get_model('app_name', 'model_name')
app_name
powinny być wymienione w cudzysłowach, tak jak powinnomodel_name
(tj. nie próbuj ich importować)get_model
akceptuje małe lub duże litery „nazwa_modelu”źródło
Większość „ciągów” modelu ma postać „nazwa_aplikacji.modelname”, więc możesz chcieć użyć tej odmiany w get_model
from django.db.models.loading import get_model your_model = get_model ( *your_string.split('.',1) )
Część kodu django, która zwykle zamienia takie łańcuchy w model, jest trochę bardziej złożona
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)
Wydaje mi się, że jest to dobry przypadek do podzielenia tego na jedną funkcję w kodzie podstawowym. Jeśli jednak wiesz, że Twoje ciągi znaków są w formacie „App.Model”, powyższe dwie linijki będą działać.
źródło
your_model = get_model(*your_string.rsplit('.', 1))
. Etykieta aplikacji ma czasem format kropkowy, jednak nazwa modelu jest zawsze prawidłowym identyfikatorem.apps.get_model
. „W skrócie ta metoda akceptuje również pojedynczy argument w formularzuapp_label.model_name
”.Błogosławionym sposobem na to w Django 1.7+ jest:
import django model_cls = django.apps.apps.get_model('app_name', 'model_name')
Tak więc w kanonicznym przykładzie wszystkich samouczków dotyczących frameworka:
import django entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
źródło
Jeśli nie wiesz, w której aplikacji istnieje Twój model, możesz przeszukać go w ten sposób:
from django.contrib.contenttypes.models import ContentType ct = ContentType.objects.get(model='your_model_name') model = ct.model_class()
Pamiętaj, że twoja_nazwa_modelu musi być zapisana małymi literami.
źródło
Nie jestem pewien, gdzie to się robi w Django, ale możesz to zrobić.
Mapowanie nazwy klasy na ciąg za pomocą odbicia.
classes = [Person,Child,Parent] def find_class(name): for clls in classes: if clls.__class__.__name__ == name: return clls
źródło
Kolejna wersja z mniejszą ilością kodu dla leniwych. Przetestowane w Django 2+
from django.apps import apps model = apps.get_model("appname.ModelName") # e.g "accounts.User"
źródło
Rozwiązanie 2020:
from django.apps import apps apps.get_model('app_name', 'Model')
na twój np .:
apps.get_model('people', 'Person')
per: Błąd importu: nie można zaimportować nazwy get_model
źródło
Oto podejście mniej specyficzne dla django, aby pobrać klasę z łańcucha:
mymodels = ['ModelA', 'ModelB'] model_list = __import__('<appname>.models', fromlist=mymodels) model_a = getattr(model_list, 'ModelA')
lub możesz użyć importlib, jak pokazano tutaj :
import importlib myapp_models = importlib.import_module('<appname>.models') model_a = getattr(myapp_models, 'ModelA')
źródło