In meiner Django-Website erstelle ich eine Klasse, die dynamisch mit anderen auf der Website installierten Anwendungen interagiert. Ich muss an jedem Feld jeder Anwendung eine Manipulation vornehmen.
Ich möchte also den Namen aller installierten Anwendungen in einer Liste speichern und die Attribute der einzelnen Anwendungen abrufen. Es gibt eine Möglichkeit, dies mit einem Iterator oder etwas anderem zu tun?
Unter Django 1.7 und höher (danke Colin Anderson):
from Django.apps import apps
apps.get_models()
Unter Django 1.6 und darunter.
Wenn Sie alle Modelle möchten, versuchen Sie Folgendes:
from Django.db.models import get_models
for model in get_models():
# Do something with your model here
print model.__name__, [x.name for x in model._meta.fields]
Ich glaube, dass die ältere Funktion noch funktioniert.
[bearbeiten]
Ab Django 1.7 wird vom Zugriff auf
settings.INSTALLED_APPS
abgeraten: " Ihr Code sollte niemals direkt auf INSTALLED_APPS zugreifen. Verwenden Sie stattdessen Django.apps.apps. " - johanno
Der gesegnete Weg ist also:
from Django.apps import apps
for app in apps.get_app_configs():
print(app.verbose_name, ":")
for model in app.get_models():
print("\t", model)
Ältere Version dieser Antwort:
Alle Anwendungen werden in der settings.py
-Datei registriert.
In [1]: from Django.conf import settings
In [2]: print(settings.INSTALLED_APPS)
['Django.contrib.auth', 'Django.contrib.contenttypes',
'Django.contrib.sessions', 'Django.contrib.sites',
'Django.contrib.messages', 'Django.contrib.staticfiles',
'Django.contrib.admin', 'raven.contrib.Django']
Sie können jede Anwendung importieren und ihre Attribute auflisten:
In [3]: from pprint import pprint
In [4]: for app_name in settings.INSTALLED_APPS:
try:
module_ = __import__(app_name)
except ImportError:
pass
map(print, ['=' * 80, "MODULE: "+app_name, '-' * 80])
pprint(module_.__dict__)
Um die neue Druckfunktion anstelle der Druckanweisung in älterem Python zu verwenden, müssen Sie möglicherweise einen from __future__ import print_function
ausgeben (oder nur die Zeile ändern, die den Aufruf print
enthält).
Die Liste der installierten Anwendungen ist in settings.INSTALLED_APPS
definiert. Es enthält einen Tupel mit Zeichenfolgen, sodass Sie darauf iterieren können, um auf den Namen der einzelnen Anwendungen zuzugreifen.
Ich bin jedoch nicht sicher, was Sie mit den attributes - und -Feldern der jeweiligen Anwendung meinen.
Sie können installierte Apps wie folgt abrufen (im Interpreter):
>>> from Django.conf import settings
>>> [ app for app in settings.INSTALLED_APPS if not "Django" in app ]
['myapp1', 'myapp2', 'myapp3']
Um die eigentlichen apps sich selbst (nicht nur Namen) zu erhalten, habe ich mir folgendes ausgedacht:
from Django.conf import settings
from Django.utils.module_loading import import_module
apps = [import_module(appname) for appname in settings.INSTALLED_APPS]
Möglicherweise möchten Sie jedoch einige Fehler behandeln oder filtern.
Getestet mit Django 1.9:
from Django.test.runner import DiscoverRunner
from Django.test import override_settings
from Django.apps import apps
class DiscoverRunnerNoMigrations(DiscoverRunner):
def run_tests(self, *args, **kwargs):
app_labels = [a.label for a in apps.app_configs.values()]
migration_modules = dict.fromkeys(app_labels)
with override_settings(MIGRATION_MODULES=migration_modules):
return super(DiscoverRunnerNoMigrations, self).run_tests(*args,
**kwargs)
Aktualisieren Sie Ihre Einstellungen, um auf diesen Testläufer zu verweisen.
Das Ausführen mit --keepdb ist sehr schnell.
Arbeitet an Django 1.11+ (Ich arbeite an Django 2.2)
from Django.conf import settings
from Django.apps import apps
# get complete list of all apps
list_of_apps = [apps.get_app_config(app_name.split('.')[-1]) \
for app_name in settings.INSTALLED_APPS]
# app_name.split('.')[-1] we need, because some system apps has dots in name
# like 'Django.contrib.admin', and app_label is 'admin'
# get list of models for one specific app. For example first app in list_of_apps
models_list = [model for name, model in list_of_apps[0].models.items() \
if not model._meta.auto_created]
# we outfiltered auto_created models, because they are not in models.py
# and had been created automatically by Django