Applications

Django contains a registry of installed applications that stores configurationand provides introspection. It also maintains a list of available models.

This registry is called apps and it’s available indjango.apps:

  1. >>> from django.apps import apps
  2. >>> apps.get_app_config('admin').verbose_name
  3. 'Administration'

Projects and applications

The term project describes a Django web application. The project Pythonpackage is defined primarily by a settings module, but it usually containsother things. For example, when you run django-admin startproject mysiteyou’ll get a mysite project directory that contains a mysite Pythonpackage with settings.py, urls.py, and wsgi.py. The project packageis often extended to include things like fixtures, CSS, and templates whicharen’t tied to a particular application.

A project’s root directory (the one that contains manage.py) is usuallythe container for all of a project’s applications which aren’t installedseparately.

The term application describes a Python package that provides some set offeatures. Applications may be reused in variousprojects.

Applications include some combination of models, views, templates, templatetags, static files, URLs, middleware, etc. They’re generally wired intoprojects with the INSTALLED_APPS setting and optionally with othermechanisms such as URLconfs, the MIDDLEWARE setting, or templateinheritance.

It is important to understand that a Django application is a set of codethat interacts with various parts of the framework. There’s no such thing asan Application object. However, there’s a few places where Django needs tointeract with installed applications, mainly for configuration and also forintrospection. That’s why the application registry maintains metadata in anAppConfig instance for each installed application.

There’s no restriction that a project package can’t also be considered anapplication and have models, etc. (which would require adding it toINSTALLED_APPS).

Configuring applications

To configure an application, subclass AppConfig and putthe dotted path to that subclass in INSTALLED_APPS.

When INSTALLED_APPS contains the dotted path to an applicationmodule, Django checks for a default_app_config variable in that module.

If it’s defined, it’s the dotted path to the AppConfigsubclass for that application.

If there is no default_app_config, Django uses the baseAppConfig class.

default_app_config allows applications that predate Django 1.7 such asdjango.contrib.admin to opt-in to AppConfig featureswithout requiring users to update their INSTALLED_APPS.

New applications should avoid default_app_config. Instead they shouldrequire the dotted path to the appropriate AppConfigsubclass to be configured explicitly in INSTALLED_APPS.

For application authors

If you’re creating a pluggable app called “Rock ’n’ roll”, here’s how youwould provide a proper name for the admin:

  1. # rock_n_roll/apps.py
  2.  
  3. from django.apps import AppConfig
  4.  
  5. class RockNRollConfig(AppConfig):
  6. name = 'rock_n_roll'
  7. verbose_name = "Rock ’n’ roll"

You can make your application load this AppConfigsubclass by default as follows:

  1. # rock_n_roll/__init__.py
  2.  
  3. default_app_config = 'rock_n_roll.apps.RockNRollConfig'

That will cause RockNRollConfig to be used when INSTALLED_APPScontains 'rock_n_roll'. This allows you to make use ofAppConfig features without requiring your users to updatetheir INSTALLED_APPS setting. Besides this use case, it’s best toavoid using default_app_config and instead specify the app config class inINSTALLED_APPS as described next.

Of course, you can also tell your users to put'rock_n_roll.apps.RockNRollConfig' in their INSTALLED_APPSsetting. You can even provide several differentAppConfig subclasses with different behaviors and allowyour users to choose one via their INSTALLED_APPS setting.

The recommended convention is to put the configuration class in a submodule ofthe application called apps. However, this isn’t enforced by Django.

You must include the name attribute for Djangoto determine which application this configuration applies to. You can defineany attributes documented in the AppConfig APIreference.

Note

If your code imports the application registry in an application’sinit.py, the name apps will clash with the apps submodule.The best practice is to move that code to a submodule and import it. Aworkaround is to import the registry under a different name:

  1. from django.apps import apps as django_apps

For application users

If you’re using “Rock ’n’ roll” in a project called anthology, but youwant it to show up as “Jazz Manouche” instead, you can provide your ownconfiguration:

  1. # anthology/apps.py
  2.  
  3. from rock_n_roll.apps import RockNRollConfig
  4.  
  5. class JazzManoucheConfig(RockNRollConfig):
  6. verbose_name = "Jazz Manouche"
  7.  
  8. # anthology/settings.py
  9.  
  10. INSTALLED_APPS = [
  11. 'anthology.apps.JazzManoucheConfig',
  12. # ...
  13. ]

Again, defining project-specific configuration classes in a submodule calledapps is a convention, not a requirement.

Application configuration

  • class AppConfig[source]
  • Application configuration objects store metadata for an application. Someattributes can be configured in AppConfigsubclasses. Others are set by Django and read-only.

Configurable attributes

  • AppConfig.name
  • Full Python path to the application, e.g. 'django.contrib.admin'.

This attribute defines which application the configuration applies to. Itmust be set in all AppConfig subclasses.

It must be unique across a Django project.

  • AppConfig.label
  • Short name for the application, e.g. 'admin'

This attribute allows relabeling an application when two applicationshave conflicting labels. It defaults to the last component of name.It should be a valid Python identifier.

It must be unique across a Django project.

  • AppConfig.verbose_name
  • Human-readable name for the application, e.g. “Administration”.

This attribute defaults to label.title().

  • AppConfig.path
  • Filesystem path to the application directory, e.g.'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'.

In most cases, Django can automatically detect and set this, but you canalso provide an explicit override as a class attribute on yourAppConfig subclass. In a few situations this isrequired; for instance if the app package is a namespace package withmultiple paths.

Read-only attributes

  • AppConfig.module
  • Root module for the application, e.g. <module 'django.contrib.admin' from'django/contrib/admin/init.py'>.

  • AppConfig.models_module

  • Module containing the models, e.g. <module 'django.contrib.admin.models'from 'django/contrib/admin/models.py'>.

It may be None if the application doesn’t contain a models module.Note that the database related signals such aspre_migrate andpost_migrateare only emitted for applications that have a models module.

Methods

  • AppConfig.get_models()[source]
  • Returns an iterable of Model classes for thisapplication.

Requires the app registry to be fully populated.

  • AppConfig.getmodel(_model_name, require_ready=True)[source]
  • Returns the Model with the givenmodel_name. model_name is case-insensitive.

Raises LookupError if no such model exists in this application.

Requires the app registry to be fully populated unless therequire_ready argument is set to False. require_ready behavesexactly as in apps.get_model().

  • AppConfig.ready()[source]
  • Subclasses can override this method to perform initialization tasks suchas registering signals. It is called as soon as the registry is fullypopulated.

Although you can’t import models at the module-level whereAppConfig classes are defined, you can import them inready(), using either an import statement orget_model().

If you’re registering model signals, youcan refer to the sender by its string label instead of using the modelclass itself.

Example:

  1. from django.db.models.signals import pre_save
  2.  
  3. def ready(self):
  4. # importing model classes
  5. from .models import MyModel # or...
  6. MyModel = self.get_model('MyModel')
  7.  
  8. # registering signals with the model's string label
  9. pre_save.connect(receiver, sender='app_label.MyModel')

Warning

Although you can access model classes as described above, avoidinteracting with the database in your ready() implementation.This includes model methods that execute queries(save(),delete(), manager methods etc.), andalso raw SQL queries via django.db.connection. Yourready() method will run during startup of every managementcommand. For example, even though the test database configuration isseparate from the production settings, manage.py test would stillexecute some queries against your production database!

Note

In the usual initialization process, the ready method is only calledonce by Django. But in some corner cases, particularly in tests whichare fiddling with installed applications, ready might be called morethan once. In that case, either write idempotent methods, or put a flagon your AppConfig classes to prevent re-running code which shouldbe executed exactly one time.

Namespace packages as apps

Python packages without an init.py file are known as “namespacepackages” and may be spread across multiple directories at different locationson sys.path (see PEP 420).

Django applications require a single base filesystem path where Django(depending on configuration) will search for templates, static assets,etc. Thus, namespace packages may only be Django applications if one of thefollowing is true:

  • The namespace package actually has only a single location (i.e. is notspread across more than one directory.)
  • The AppConfig class used to configure the applicationhas a path class attribute, which is theabsolute directory path Django will use as the single base path for theapplication.If neither of these conditions is met, Django will raiseImproperlyConfigured.

Application registry

  • apps
  • The application registry provides the following public API. Methods thataren’t listed below are considered private and may change without notice.

  • apps.ready

  • Boolean attribute that is set to True after the registry is fullypopulated and all AppConfig.ready() methods are called.

  • apps.get_app_configs()

  • Returns an iterable of AppConfig instances.

  • apps.getapp_config(_app_label)

  • Returns an AppConfig for the application with thegiven app_label. Raises LookupError if no such applicationexists.

  • apps.isinstalled(_app_name)

  • Checks whether an application with the given name exists in the registry.app_name is the full name of the app, e.g. 'django.contrib.admin'.

  • apps.getmodel(_app_label, model_name, require_ready=True)

  • Returns the Model with the given app_labeland model_name. As a shortcut, this method also accepts a singleargument in the form app_label.model_name. model_name iscase-insensitive.

Raises LookupError if no such application or model exists. RaisesValueError when called with a single argument that doesn’t containexactly one dot.

Requires the app registry to be fully populated unless therequire_ready argument is set to False.

Setting require_ready to False allows looking up modelswhile the app registry is being populated,specifically during the second phase where it imports models. Thenget_model() has the same effect as importing the model. The main usecase is to configure model classes with settings, such asAUTH_USER_MODEL.

When require_ready is False, get_model() returns a model classthat may not be fully functional (reverse accessors may be missing, forexample) until the app registry is fully populated. For this reason, it’sbest to leave require_ready to the default value of True wheneverpossible.

Initialization process

How applications are loaded

When Django starts, django.setup() is responsible for populating theapplication registry.

  • setup(set_prefix=True)[source]
  • Configures Django by:

    • Loading the settings.
    • Setting up logging.
    • If set_prefix is True, setting the URL resolver script prefix toFORCE_SCRIPT_NAME if defined, or / otherwise.
    • Initializing the application registry.This function is called automatically:

    • When running an HTTP server via Django’s WSGI support.

    • When invoking a management command.It must be called explicitly in other cases, for instance in plain Pythonscripts.

The application registry is initialized in three stages. At each stage, Djangoprocesses all applications in the order of INSTALLED_APPS.

If it’s an application configuration class, Django imports the root packageof the application, defined by its name attribute. Ifit’s a Python package, Django creates a default application configuration.

At this stage, your code shouldn’t import any models!

In other words, your applications’ root packages and the modules thatdefine your application configuration classes shouldn’t import any models,even indirectly.

Strictly speaking, Django allows importing models once their applicationconfiguration is loaded. However, in order to avoid needless constraints onthe order of INSTALLED_APPS, it’s strongly recommended notimport any models at this stage.

Once this stage completes, APIs that operate on application configurationssuch as get_app_config() become usable.

  • Then Django attempts to import the models submodule of each application,if there is one.

You must define or import all models in your application’s models.py ormodels/init.py. Otherwise, the application registry may not be fullypopulated at this point, which could cause the ORM to malfunction.

Once this stage completes, APIs that operate on models such asget_model() become usable.

  • Finally Django runs the ready() method of each applicationconfiguration.

Troubleshooting

Here are some common problems that you may encounter during initialization:

  • AppRegistryNotReady: This happens whenimporting an application configuration or a models module triggers code thatdepends on the app registry.

For example, gettext() uses the appregistry to look up translation catalogs in applications. To translate atimport time, you need gettext_lazy()instead. (Using gettext() would be a bug,because the translation would happen at import time, rather than at eachrequest depending on the active language.)

Executing database queries with the ORM at import time in models moduleswill also trigger this exception. The ORM cannot function properly until allmodels are available.

This exception also happens if you forget to call django.setup() ina standalone Python script.

  • ImportError: cannot import name … This happens if the import sequenceends up in a loop.

To eliminate such problems, you should minimize dependencies between yourmodels modules and do as little work as possible at import time. To avoidexecuting code at import time, you can move it into a function and cache itsresults. The code will be executed when you first need its results. Thisconcept is known as “lazy evaluation”.

  • django.contrib.admin automatically performs autodiscovery of adminmodules in installed applications. To prevent it, change yourINSTALLED_APPS to contain'django.contrib.admin.apps.SimpleAdminConfig' instead of'django.contrib.admin'.