Get a list of all installed applications in Django and their attributes

后端 未结 7 1349
一个人的身影
一个人的身影 2020-12-13 17:32

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 app

相关标签:
7条回答
  • 2020-12-13 18:06

    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.

    0 讨论(0)
  • 2020-12-13 18:06

    [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).

    0 讨论(0)
  • 2020-12-13 18:12

    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
    
    0 讨论(0)
  • 2020-12-13 18:13

    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.

    0 讨论(0)
  • 2020-12-13 18:15

    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']
    
    0 讨论(0)
  • 2020-12-13 18:20

    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.

    0 讨论(0)
提交回复
热议问题