55

In my Django website, I'm creating a class that interact dynamically with other applications installed in the website. I have to do a manipulation on each field of each application.

So I want to save the name of all installed applications in a list and get the attributes of each one. There is a way to do that using an iterator or something else ?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
bnabilos
  • 2,234
  • 4
  • 23
  • 30

7 Answers7

84

Under Django 1.7 and above (thanks Colin Anderson):

from django.apps import apps
apps.get_models()

Under Django 1.6 and below.

If you want all models, try:

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]

I believe the older function still works.

guettli
  • 25,042
  • 81
  • 346
  • 663
Matthew Schinckel
  • 35,041
  • 6
  • 86
  • 121
  • 2
    Helped me a lot. +1ed the question as well, even if it was the wrong question for the right answer ;-) – AndreasT Jan 25 '12 at 11:48
  • 7
    in django 1.7: from django.apps import apps; apps.get_models() – Collin Anderson Mar 28 '14 at 02:57
  • @Matthew How can i use app names and model name in django template to create menu ? – Ajinkya Bhosale May 08 '16 at 11:12
  • @AjinkyaBhosale for what purpose? Consider writing a complete question (explaining _exactly_ what it is you are trying to do). – Matthew Schinckel May 08 '16 at 22:46
  • 8
    Didn't the OP asked for list of all installed apps.. Not the list of all models... – Anoop Nair Apr 24 '19 at 09:23
  • Possibly, but they did say "Perfect!" in response, so I guess not. – Matthew Schinckel Apr 29 '19 at 06:19
  • See also the comments to the other answers: they were actually looking for models, it was just not clearly outlined. – Matthew Schinckel Apr 29 '19 at 06:20
  • 12
    In case anyone *does* come here looking for how to get a list of (names of) installed apps, I did it in Django 1.11 with `apps.app_configs.keys()`. This yields a list of app labels. It does the same thing as @caio's response below, but is a little more direct. `apps.app_configs` yields a dictionary with the app labels as keys. – nttaylor May 31 '19 at 20:28
41

[edit]

Since Django 1.7, accessing settings.INSTALLED_APPS is discouraged: "Your code should never access INSTALLED_APPS directly. Use django.apps.apps instead." – johanno

So the blessed way is:

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)

Older version of this answer:

All applications are registered in the settings.py file.

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']

You can import each application and list their attributes:

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__)

In order to use the new print function instead of the print statement in older Python you may have to issue a from __future__ import print_function (or just change the line containing the print call).

Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
  • 3
    Since at least Django 1.7, accessing settings.INSTALLED_APPS is discouraged: ["Your code should never access INSTALLED_APPS directly. Use django.apps.apps instead."](https://docs.djangoproject.com/en/1.7/ref/settings/#installed-apps) – johanno May 09 '17 at 20:00
14

You can retrieve installed apps like that (in interpreter) :

>>> from django.conf import settings
>>> [app for app in settings.INSTALLED_APPS
     if not app.startswith("django.")]
['myapp1', 'myapp2', 'myapp3']
Zulu
  • 8,765
  • 9
  • 49
  • 56
9

The list of installed applications is defined in settings.INSTALLED_APPS. It contains a tuple of strings, so you can iterate on it to access each application's name.

However, I'm not sure what you mean by each application's attributes and fields.

André Caron
  • 44,541
  • 12
  • 67
  • 125
  • For attributes, If I have for example an application with 2 CharField and 2 TextField, I want to be able to get these fields data when I select it. I want to do that for each application installed so it should be dynamic and not hard coded. Thank you – bnabilos Nov 06 '10 at 00:47
  • Applications don't have `CharField` and `TextField` "attributes". Are you talking about application models or application forms? – André Caron Nov 06 '10 at 01:05
  • 1
    I'm sorry for not explaining that well, I'm talking about application models : http://docs.djangoproject.com/en/dev/ref/models/fields/#field-types – bnabilos Nov 06 '10 at 01:29
4

To get the actual apps themselves (not just names), this is what I came up with:

from django.conf import settings
from django.utils.module_loading import import_module
apps = [import_module(appname) for appname in settings.INSTALLED_APPS]

Though you may want to do some error handling, or filtering.

Cj Welborn
  • 119
  • 1
  • 5
0

Tested with 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)

Update your settings to point to this test runner.

Running this with --keepdb is real fast.

caio
  • 1,949
  • 16
  • 20
0

Works on Django 1.11+ (I'm working on 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