============
Applications
============

.. module:: django.apps

Django contains a registry of installed applications that stores configuration
and provides introspection. It also maintains a list of available :doc:`models
</topics/db/models>`.

This registry is called :attr:`~django.apps.apps` and it's available in
:mod:`django.apps`::

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

Projects and applications
=========================

The term **project** describes a Django web application. The project Python
package is defined primarily by a settings module, but it usually contains
other things. For example, when you run  ``django-admin startproject mysite``
you'll get a ``mysite`` project directory that contains a ``mysite`` Python
package with ``settings.py``, ``urls.py``, ``asgi.py`` and ``wsgi.py``. The
project package is often extended to include things like fixtures, CSS, and
templates which aren't tied to a particular application.

A **project's root directory** (the one that contains ``manage.py``) is usually
the container for all of a project's applications which aren't installed
separately.

The term **application** describes a Python package that provides some set of
features. Applications :doc:`may be reused </intro/reusable-apps/>` in various
projects.

Applications include some combination of models, views, templates, template
tags, static files, URLs, middleware, etc. They're generally wired into
projects with the :setting:`INSTALLED_APPS` setting and optionally with other
mechanisms such as URLconfs, the :setting:`MIDDLEWARE` setting, or template
inheritance.

It is important to understand that a Django application is a set of code
that interacts with various parts of the framework. There's no such thing as
an ``Application`` object. However, there's a few places where Django needs to
interact with installed applications, mainly for configuration and also for
introspection. That's why the application registry maintains metadata in an
:class:`~django.apps.AppConfig` instance for each installed application.

There's no restriction that a project package can't also be considered an
application and have models, etc. (which would require adding it to
:setting:`INSTALLED_APPS`).

.. _configuring-applications-ref:

Configuring applications
========================

To configure an application, create an ``apps.py`` module inside the
application, then define a subclass of :class:`AppConfig` there.

When :setting:`INSTALLED_APPS` contains the dotted path to an application
module, by default, if Django finds exactly one :class:`AppConfig` subclass in
the ``apps.py`` submodule, it uses that configuration for the application. This
behavior may be disabled by setting :attr:`AppConfig.default` to ``False``.

If the ``apps.py`` module contains more than one :class:`AppConfig` subclass,
Django will look for a single one where :attr:`AppConfig.default` is ``True``.

If no :class:`AppConfig` subclass is found, the base :class:`AppConfig` class
will be used.

Alternatively, :setting:`INSTALLED_APPS` may contain the dotted path to a
configuration class to specify it explicitly::

    INSTALLED_APPS = [
        ...
        'polls.apps.PollsAppConfig',
        ...
    ]

For application authors
-----------------------

If you're creating a pluggable app called "Rock ’n’ roll", here's how you
would provide a proper name for the admin::

    # rock_n_roll/apps.py

    from django.apps import AppConfig

    class RockNRollConfig(AppConfig):
        name = 'rock_n_roll'
        verbose_name = "Rock ’n’ roll"

``RockNRollConfig`` will be loaded automatically when :setting:`INSTALLED_APPS`
contains ``'rock_n_roll'``. If you need to prevent this, set
:attr:`~AppConfig.default` to ``False`` in the class definition.

You can provide several :class:`AppConfig` subclasses with different behaviors.
To tell Django which one to use by default, set :attr:`~AppConfig.default` to
``True`` in its definition. If your users want to pick a non-default
configuration, they must replace ``'rock_n_roll'`` with the dotted path to that
specific class in their :setting:`INSTALLED_APPS` setting.

The :attr:`AppConfig.name` attribute tells Django which application this
configuration applies to. You can define any other attribute documented in the
:class:`~django.apps.AppConfig` API reference.

:class:`AppConfig` subclasses may be defined anywhere. The ``apps.py``
convention merely allows Django to load them automatically when
:setting:`INSTALLED_APPS` contains the path to an application module rather
than the path to a configuration class.

.. note::

    If your code imports the application registry in an application's
    ``__init__.py``, the name ``apps`` will clash with the ``apps`` submodule.
    The best practice is to move that code to a submodule and import it. A
    workaround is to import the registry under a different name::

        from django.apps import apps as django_apps

.. versionchanged:: 3.2

    In previous versions, a ``default_app_config`` variable in the application
    module was used to identify the default application configuration class.

For application users
---------------------

If you're using "Rock ’n’ roll" in a project called ``anthology``, but you
want it to show up as "Jazz Manouche" instead, you can provide your own
configuration::

    # anthology/apps.py

    from rock_n_roll.apps import RockNRollConfig

    class JazzManoucheConfig(RockNRollConfig):
        verbose_name = "Jazz Manouche"

    # anthology/settings.py

    INSTALLED_APPS = [
        'anthology.apps.JazzManoucheConfig',
        # ...
    ]

This example shows project-specific configuration classes located in a
submodule called ``apps.py``. This is a convention, not a requirement.
:class:`AppConfig` subclasses may be defined anywhere.

In this situation, :setting:`INSTALLED_APPS` must contain the dotted path to
the configuration class because it lives outside of an application and thus
cannot be automatically detected.

Application configuration
=========================

.. class:: AppConfig

    Application configuration objects store metadata for an application. Some
    attributes can be configured in :class:`~django.apps.AppConfig`
    subclasses. Others are set by Django and read-only.

Configurable attributes
-----------------------

.. attribute:: AppConfig.name

    Full Python path to the application, e.g. ``'django.contrib.admin'``.

    This attribute defines which application the configuration applies to. It
    must be set in all :class:`~django.apps.AppConfig` subclasses.

    It must be unique across a Django project.

.. attribute:: AppConfig.label

    Short name for the application, e.g. ``'admin'``

    This attribute allows relabeling an application when two applications
    have 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.

.. attribute:: AppConfig.verbose_name

    Human-readable name for the application, e.g. "Administration".

    This attribute defaults to ``label.title()``.

.. attribute:: 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 can
    also provide an explicit override as a class attribute on your
    :class:`~django.apps.AppConfig` subclass. In a few situations this is
    required; for instance if the app package is a `namespace package`_ with
    multiple paths.

.. attribute:: AppConfig.default

    .. versionadded:: 3.2

    Set this attribute to ``False`` to prevent Django from selecting a
    configuration class automatically. This is useful when ``apps.py`` defines
    only one :class:`AppConfig` subclass but you don't want Django to use it by
    default.

    Set this attribute to ``True`` to tell Django to select a configuration
    class automatically. This is useful when ``apps.py`` defines more than one
    :class:`AppConfig` subclass and you want Django to use one of them by
    default.

    By default, this attribute isn't set.

.. attribute:: AppConfig.default_auto_field

    .. versionadded:: 3.2

    The implicit primary key type to add to models within this app. You can
    use this to keep :class:`~django.db.models.AutoField` as the primary key
    type for third party applications.

    By default, this is the value of :setting:`DEFAULT_AUTO_FIELD`.

Read-only attributes
--------------------

.. attribute:: AppConfig.module

    Root module for the application, e.g. ``<module 'django.contrib.admin' from
    'django/contrib/admin/__init__.py'>``.

.. attribute:: 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 as
    :data:`~django.db.models.signals.pre_migrate` and
    :data:`~django.db.models.signals.post_migrate`
    are only emitted for applications that have a ``models`` module.

Methods
-------

.. method:: AppConfig.get_models()

    Returns an iterable of :class:`~django.db.models.Model` classes for this
    application.

    Requires the app registry to be fully populated.

.. method:: AppConfig.get_model(model_name, require_ready=True)

    Returns the :class:`~django.db.models.Model` with the given
    ``model_name``. ``model_name`` is case-insensitive.

    Raises :exc:`LookupError` if no such model exists in this application.

    Requires the app registry to be fully populated unless the
    ``require_ready`` argument is set to ``False``. ``require_ready`` behaves
    exactly as in :meth:`apps.get_model()`.

.. method:: AppConfig.ready()

    Subclasses can override this method to perform initialization tasks such
    as registering signals. It is called as soon as the registry is fully
    populated.

    Although you can't import models at the module-level where
    :class:`~django.apps.AppConfig` classes are defined, you can import them in
    ``ready()``, using either an ``import`` statement or
    :meth:`~AppConfig.get_model`.

    If you're registering :mod:`model signals <django.db.models.signals>`, you
    can refer to the sender by its string label instead of using the model
    class itself.

    Example::

        from django.apps import AppConfig
        from django.db.models.signals import pre_save


        class RockNRollConfig(AppConfig):
            # ...

            def ready(self):
                # importing model classes
                from .models import MyModel  # or...
                MyModel = self.get_model('MyModel')

                # registering signals with the model's string label
                pre_save.connect(receiver, sender='app_label.MyModel')

    .. warning::

        Although you can access model classes as described above, avoid
        interacting with the database in your :meth:`ready()` implementation.
        This includes model methods that execute queries
        (:meth:`~django.db.models.Model.save()`,
        :meth:`~django.db.models.Model.delete()`, manager methods etc.), and
        also raw SQL queries via ``django.db.connection``. Your
        :meth:`ready()` method will run during startup of every management
        command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        