2010-11-06 77 views
29

在我的Django網站中,我創建了一個與網站中安裝的其他應用程序動態交互的類。我必須對每個應用程序的每個字段進行操作。獲取Django中所有安裝的應用程序及其屬性列表

因此,我想將所有已安裝的應用程序的名稱保存在列表中,並獲取每個應用程序的屬性。有一種方法可以使用迭代器或其他方法做到這一點?

+0

從'manage.py' CLI:http://stackoverflow.com/questions/21566919/django-listing-installed-apps – 2016-05-14 09:30:07

回答

53

在Django的1.7及以上(感謝安德森柯林):

from django.apps import apps 
apps.get_models() 

在Django的1.6及以下。

如果你想所有機型,請嘗試:

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] 

我相信舊的功能仍然有效。

+0

完美!非常感謝 – bnabilos 2010-11-06 12:19:19

+2

幫了我很多。 + 1也是這個問題,即使它是正確答案的錯誤問題;-) django 1.7中的 – AndreasT 2012-01-25 11:48:59

+5

:來自django.apps import apps; apps.get_models() – 2014-03-28 02:57:18

7

安裝的應用程序列表在settings.INSTALLED_APPS中定義。它包含一個字符串元組,因此您可以迭代它以訪問每個應用程序的名稱。

不過,我不知道你的每個應用程序的屬性領域的意思。

+0

的屬性,如果我有例如2 CharField和2文本字段的應用程序,我想當我選擇它時能夠獲得這些字段的數據。我想爲每個安裝的應用程序都這樣做,所以它應該是動態的而不是硬編碼的。謝謝 – bnabilos 2010-11-06 00:47:36

+0

應用程序沒有'CharField'和'TextField'「屬性」。你在談論應用程序模型還是應用程序表單? – 2010-11-06 01:05:32

+1

我很抱歉沒有解釋得那麼好,我在談論應用程序模型:http://docs.djangoproject.com/en/dev/ref/models/fields/#field-types – bnabilos 2010-11-06 01:29:29

13

[編輯]

由於Django的1.7,訪問settings.INSTALLED_APPS氣餒: 「Your code should never access INSTALLED_APPS directly. Use django.apps.apps instead.」 - johanno

所以祝福的方式是:這

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) 

舊版本回答:

所有應用程序都在settings.py文件中註冊。

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

可以導入每一個應用程序,並列出它們的屬性:

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

爲了在老的Python使用新的打印功能,而不是打印語句,你可能不得不發出from __future__ import print_function(或只是更改包含print調用的行)。

+1

由於至少Django 1.7,訪問settings.INSTALLED_APPS不鼓勵:[「你的代碼不應該直接訪問INSTALLED_APPS,而是使用django.apps.apps」](https://docs.djangoproject.com/en/1.7/ref/settings/#installed-apps ) – johanno 2017-05-09 20:00:39

7

您可以檢索已安裝的應用程序一樣,(在翻譯):

>>> from django.conf import settings 
>>> [ app for app in settings.INSTALLED_APPS if not "django" in app ] 
['myapp1', 'myapp2', 'myapp3'] 
3

要獲得實際應用本身(不僅僅是名稱),這是我想出了:

雖然你可能想要做一些錯誤處理或過濾。

0

經過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) 

更新您的設置以指向此測試運行器。

使用--keepdb運行該功能非常快。

相關問題