123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- ============
- 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`:
- .. code-block:: pycon
- >>> 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
- 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.
- .. warning::
- Changing this attribute after migrations have been applied for an
- application will result in breaking changes to a project or, in the
- case of a reusable app, any existing installs of that app. This is
- because ``AppConfig.label`` is used in database tables and migration
- files when referencing an app in the dependencies list.
- .. 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
- 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
- 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(include_auto_created=False, include_swapped=False)
- 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. For example, even though the test database configuration is
- separate from the production settings, ``manage.py test`` would still
- execute some queries against your **production** database!
- .. note::
- In the usual initialization process, the ``ready`` method is only called
- once by Django. But in some corner cases, particularly in tests which
- are fiddling with installed applications, ``ready`` might be called more
- than once. In that case, either write idempotent methods, or put a flag
- on your ``AppConfig`` classes to prevent rerunning code which should
- be executed exactly one time.
- .. _namespace package:
- Namespace packages as apps
- --------------------------
- Python packages without an ``__init__.py`` file are known as "namespace
- packages" and may be spread across multiple directories at different locations
- on ``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 the
- following is true:
- #. The namespace package actually has only a single location (i.e. is not
- spread across more than one directory.)
- #. The :class:`~django.apps.AppConfig` class used to configure the application
- has a :attr:`~django.apps.AppConfig.path` class attribute, which is the
- absolute directory path Django will use as the single base path for the
- application.
- If neither of these conditions is met, Django will raise
- :exc:`~django.core.exceptions.ImproperlyConfigured`.
- Application registry
- ====================
- .. data:: apps
- The application registry provides the following public API. Methods that
- aren't listed below are considered private and may change without notice.
- .. attribute:: apps.ready
- Boolean attribute that is set to ``True`` after the registry is fully
- populated and all :meth:`AppConfig.ready` methods are called.
- .. method:: apps.get_app_configs()
- Returns an iterable of :class:`~django.apps.AppConfig` instances.
- .. method:: apps.get_app_config(app_label)
- Returns an :class:`~django.apps.AppConfig` for the application with the
- given ``app_label``. Raises :exc:`LookupError` if no such application
- exists.
- .. method:: apps.is_installed(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'``.
- .. method:: apps.get_model(app_label, model_name, require_ready=True)
- Returns the :class:`~django.db.models.Model` with the given ``app_label``
- and ``model_name``. As a shortcut, this method also accepts a single
- argument in the form ``app_label.model_name``. ``model_name`` is
- case-insensitive.
- Raises :exc:`LookupError` if no such application or model exists. Raises
- :exc:`ValueError` when called with a single argument that doesn't contain
- exactly one dot.
- Requires the app registry to be fully populated unless the
- ``require_ready`` argument is set to ``False``.
- Setting ``require_ready`` to ``False`` allows looking up models
- :ref:`while the app registry is being populated <app-loading-process>`,
- specifically during the second phase where it imports models. Then
- ``get_model()`` has the same effect as importing the model. The main use
- case is to configure model classes with settings, such as
- :setting:`AUTH_USER_MODEL`.
- When ``require_ready`` is ``False``, ``get_model()`` returns a model class
- that may not be fully functional (reverse accessors may be missing, for
- example) until the app registry is fully populated. For this reason, it's
- best to leave ``require_ready`` to the default value of ``True`` whenever
- possible.
- .. _app-loading-process:
- Initialization process
- ======================
- How applications are loaded
- ---------------------------
- When Django starts, :func:`django.setup()` is responsible for populating the
- application registry.
- .. currentmodule:: django
- .. function:: setup(set_prefix=True)
- Configures Django by:
- * Loading the settings.
- * Setting up logging.
- * If ``set_prefix`` is True, setting the URL resolver script prefix to
- :setting:`FORCE_SCRIPT_NAME` if defined, or ``/`` otherwise.
- * Initializing the application registry.
- This function is called automatically:
- * When running an HTTP server via Django's ASGI or WSGI support.
- * When invoking a management command.
- It must be called explicitly in other cases, for instance in plain Python
- scripts.
- .. currentmodule:: django.apps
- The application registry is initialized in three stages. At each stage, Django
- processes all applications in the order of :setting:`INSTALLED_APPS`.
- #. First Django imports each item in :setting:`INSTALLED_APPS`.
- If it's an application configuration class, Django imports the root package
- of the application, defined by its :attr:`~AppConfig.name` attribute. If
- it's a Python package, Django looks for an application configuration in an
- ``apps.py`` submodule, or else 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 that
- define your application configuration classes shouldn't import any models,
- even indirectly.
- Strictly speaking, Django allows importing models once their application
- configuration is loaded. However, in order to avoid needless constraints on
- the order of :setting:`INSTALLED_APPS`, it's strongly recommended not
- import any models at this stage.
- Once this stage completes, APIs that operate on application configurations
- such as :meth:`~apps.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`` or
- ``models/__init__.py``. Otherwise, the application registry may not be fully
- populated at this point, which could cause the ORM to malfunction.
- Once this stage completes, APIs that operate on models such as
- :meth:`~apps.get_model()` become usable.
- #. Finally Django runs the :meth:`~AppConfig.ready()` method of each application
- configuration.
- .. _applications-troubleshooting:
- Troubleshooting
- ---------------
- Here are some common problems that you may encounter during initialization:
- * :class:`~django.core.exceptions.AppRegistryNotReady`: This happens when
- importing an application configuration or a models module triggers code that
- depends on the app registry.
- For example, :func:`~django.utils.translation.gettext()` uses the app
- registry to look up translation catalogs in applications. To translate at
- import time, you need :func:`~django.utils.translation.gettext_lazy()`
- instead. (Using :func:`~django.utils.translation.gettext()` would be a bug,
- because the translation would happen at import time, rather than at each
- request depending on the active language.)
- Executing database queries with the ORM at import time in models modules
- will also trigger this exception. The ORM cannot function properly until all
- models are available.
- This exception also happens if you forget to call :func:`django.setup()` in
- a standalone Python script.
- * ``ImportError: cannot import name ...`` This happens if the import sequence
- ends up in a loop.
- To eliminate such problems, you should minimize dependencies between your
- models modules and do as little work as possible at import time. To avoid
- executing code at import time, you can move it into a function and cache its
- results. The code will be executed when you first need its results. This
- concept is known as "lazy evaluation".
- * ``django.contrib.admin`` automatically performs autodiscovery of ``admin``
- modules in installed applications. To prevent it, change your
- :setting:`INSTALLED_APPS` to contain
- ``'django.contrib.admin.apps.SimpleAdminConfig'`` instead of
- ``'django.contrib.admin'``.
- * ``RuntimeWarning: Accessing the database during app initialization is
- discouraged.`` This warning is triggered for database queries executed before
- apps are ready, such as during module imports or in the
- :meth:`AppConfig.ready` method. Such premature database queries are
- discouraged because they will run during the startup of every management
- command, which will slow down your project startup, potentially cache stale
- data, and can even fail if migrations are pending.
- For example, a common mistake is making a database query to populate form
- field choices::
- class LocationForm(forms.Form):
- country = forms.ChoiceField(choices=[c.name for c in Country.objects.all()])
- In the example above, the query from ``Country.objects.all()`` is executed
- during module import, because the ``QuerySet`` is iterated over. To avoid the
- warning, the form could use a :class:`~django.forms.ModelChoiceField`
- instead::
- class LocationForm(forms.Form):
- country = forms.ModelChoiceField(queryset=Country.objects.all())
- To make it easier to find the code that triggered this warning, you can make
- Python :ref:`treat warnings as errors <python:warning-filter>` to reveal the
- stack trace, for example with ``python -Werror manage.py shell``.
|