# Documentation Django 5.2.8

# Applications

Django contient un registre des applications installées qui stocke la configuration et fournit l’introspection. Il maintient également une liste des modèles disponibles.

Ce registre est appelé `apps` et est disponible dans `django.apps`:

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

## Projets et applications

Le terme projet décrit une application web Django. Le paquet Python du projet est définit principalement par un module de réglages `settings`, mais il contient généralement d’autres choses. Par exemple, lorsque vous exécutez `django-admin startproject monsite`, vous obtenez un répertoire de projet `monsite` contenant un paquet Python `monsite` avec les fichiers `settings.py`, `urls.py`, `asgi.py` et `wsgi.py`. Le paquet de projet est souvent étendu par l’ajout de choses comme des instantanés, des fichiers CSS et des gabarits qui ne sont pas liés à une application particulière.

Un répertoire racine de projet (celui qui contient `manage.py`) est généralement un conteneur pour toutes les applications d’un projet qui ne sont pas installées séparément.

Le terme application décrit un paquet Python qui fournit un certain ensemble de fonctionnalités. Les applications peuvent être réutilisées dans différents projets.

Les applications comprennent une combinaison de modèles, vues, gabarits, balises de gabarits, fichiers statiques, URL, intergiciels, etc. Elles sont généralement liées à des projets via le réglage `INSTALLED_APPS` et éventuellement avec d’autres mécanismes tels que les configurations d’URL, le réglage `MIDDLEWARE` ou l’héritage de gabarit.

Il est important de comprendre qu’une application Django est un ensemble de code qui interagit avec les différentes parties du système. Il n’existe pas d’objet `Application` en tant que tel. Cependant, il y a quelques endroits où Django a besoin d’interagir avec les applications installées, principalement pour la configuration et aussi l’introspection. C’est pourquoi le registre des applications maintient des métadonnées dans une instance de `AppConfig` pour chaque application installée.

Il n’y a pas restriction au fait qu’un paquet de projet ne puisse pas aussi être considéré comme une application et qu’il contienne des modèles, etc. (ce qui demanderait de l’ajouter dans la liste `INSTALLED_APPS`).

## Configuration des applications

Pour configurer une application, créez un module `apps.py` dans l’application, puis définissez une sous-classe de `AppConfig` dans ce fichier.

Lorsque `INSTALLED_APPS` contient le chemin en syntaxe pointée vers le module d’une application, et que Django trouve exactement une sous-classe de `AppConfig` dans le sous-module `apps.py`, il utilise par défaut cette configuration pour l’application. Ce comportement peut être désactivé en définissant `AppConfig.default` à `False`.

Si le module `apps.py` contient plus d’une sous-classe `AppConfig`, Django en cherche une seule ayant l’attribut `AppConfig.default` à `True`.

Si aucune sous-classe de `AppConfig` n’est trouvée, la classe `AppConfig` de base est utilisée.

Il est aussi possible de mettre dans `INSTALLED_APPS` le chemin à syntaxe pointée explicite vers une classe de configuration précise

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

### Pour les auteurs d’applications

Si vous créez une application réutilisable appelée « Rock “n” roll », voici comment vous pourriez définir un nom approprié pour l’interface d’administration :

    # rock_n_roll/apps.py

    from django.apps import AppConfig

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

`RockNRollConfig` sera chargée automatiquement si `INSTALLED_APPS` contient `'rock_n_roll'`. Si vous voulez empêcher cela, définissez `default` à `False` dans la définition de la classe.

Vous pouvez écrire plusieurs sous-classes `AppConfig` avec différents comportements. Pour indiquer à Django la classe à utiliser par défaut, définissez l’attribut `default` de la classe à `True`. Si un utilisateur de l’application souhaite choisir une configuration qui n’est pas celle par défaut, il doit remplacer `'rock_n_roll'` par le chemin à syntaxe pointée vers cette classe spécifique dans son réglage `INSTALLED_APPS`.

L’attribut `AppConfig.name` indique à Django à quelle application cette configuration s’applique. Vous pouvez définir tout autre attribut documenté dans la référence de l’API de `AppConfig`.

Les sous-classes de `AppConfig` peuvent être définies n’importe où. La convention `apps.py` ne sert qu’à indiquer à Django comment charger automatiquement la configuration lorsque `INSTALLED_APPS` contient le chemin vers le module principal d’une application plutôt que le chemin vers sa classe de configuration.

Note

Si votre code importe le registre des applications dans le fichier `__init__.py` d’une application, le nom `apps` entrera en conflit avec le sous-module `apps`. La meilleure approche consiste à déplacer ce code vers un sous-module et de l’importer. Une solution de contournement consiste à importer le registre sous un nom différent :

    from django.apps import apps as django_apps

### Pour les utilisateurs d’applications

Si vous utilisez « Rock “n” roll » dans un projet appelé `anthology`, mais que vous souhaitez plutôt qu’il apparaisse comme « Jazz Manouche », vous pouvez fournir votre propre 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",
        # ...
    ]

Cet exemple montre des classes de configuration spécifiques au projet situées dans un sous-module appelé `apps.py`. Ceci est une convention, pas une obligation. Les sous-classes `AppConfig` peuvent être définies n’importe où.

Dans cette situation, `INSTALLED_APPS` doit contenir le chemin à syntaxe pointée vers la classe de configuration, car celle-ci se trouve en dehors d’une application et ne peut donc pas être automatiquement détectée.

## Configuration d’applications

class AppConfig

  Les objets de configuration d’application stockent les métadonnées d’une application. Certains attributs peuvent être configurés dans des sous-classes de `AppConfig`. D’autres sont définis par Django et sont en lecture seule.

### Attributs configurables

AppConfig.name

  Chemin Python complet vers l’application, par ex. `'django.contrib.admin'`.

  Cet attribut détermine à quelle application la configuration s’applique. Il doit être défini dans toutes les sous-classes de `AppConfig`.

  Il doit être unique dans le contexte d’un même projet Django.

AppConfig.label

  Nom court de l’application, par ex. `'admin'`

  Cet attribut permet de ré-étiqueter une application lorsque deux applications ont des étiquettes incompatibles. Par défaut, `label` est le dernier élément de `name`. Il doit être un identifiant Python valide.

  Il doit être unique dans le contexte d’un même projet Django.

  Avertissement

  La modification de cet attribut après que les migrations d’une application ont été appliquées aboutira à des changements nocifs au projet ou, dans le cas d’une application réutilisable, à toute installation de cette application. Ceci parce que `AppConfig.label` est utilisée dans les tables de bases de données et les fichiers de migration lorsqu’on fait référence à une application dans la liste des dépendances.

AppConfig.verbose_name

  Nom convivial de l’application, par ex. « Administration ».

  Par défaut, cet attribut est équivalent à `label.title()`.

AppConfig.path

  Chemin du système de fichiers vers le répertoire de l’application, par ex. `'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'`.

  Dans la plupart des cas, Django peut automatiquement détecter et définir cet attribut, mais vous pouvez également fournir une dérogation explicite comme attribut de classe sur la sous-classe de `AppConfig`. Dans certains cas, c’est une nécessité ; par exemple, si le paquet de l’application est un paquet avec espace de noms comprenant plusieurs chemins.

AppConfig.default

  Définissez cet attribut à `False` pour empêcher Django de choisir automatiquement une classe de configuration. C’est utile lorsque `apps.py` définit une seule sous-classe `AppConfig` mais que vous ne souhaitez pas que celle-ci soit choisie par défaut.

  Définissez cet attribut à `True` pour indiquer à Django de choisir automatiquement une classe de configuration. C’est utile lorsque `apps.py` définit plus d’une sous-classe `AppConfig` et que vous souhaitez que Django en utilise une par défaut.

  Par défaut, cet attribut n’est pas défini.

AppConfig.default_auto_field

  Le type implicite de clé primaire à ajouter aux modèles de cette application. Vous pouvez utiliser cet attribut pour conserver `AutoField` comme type de clé primaire pour des applications réutilisables.

  Par défaut, il s’agit de la valeur du réglage `DEFAULT_AUTO_FIELD`.

### Attributs en lecture seule

AppConfig.module

  Module racine de l’application, par ex. `<module 'django.contrib.admin' from 'django/contrib/admin/__init__.py'>`.

AppConfig.models_module

  Module contenant les modèles, par ex. `<module 'django.contrib.admin.models' from 'django/contrib/admin/models.py'>`.

  Il peut valoir `None` si l’application ne contient pas de module `models`. Notez que les signaux relatifs à la base de données tels que `pre_migrate` et `post_migrate` ne sont émis que pour les applications qui ont un module `models`.

### Méthodes

AppConfig.get_models(include_auto_created=False, include_swapped=False)

  Renvoie un objet itérable de classes `Model` pour cette application.

  Nécessite que le registre des applications soit complètement défini.

AppConfig.get_model(model_name, require_ready=True)

  Renvoie la classe `Model` ayant le nom `model_name` donné. `model_name` est insensible à la casse.

  Génère `LookupError` si aucun modèle de ce nom n’existe dans cette application.

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

AppConfig.ready()

  Les sous-classes peuvent étendre cette méthode pour effectuer des tâches d’initialisation telles que l’enregistrement de signaux. Elle est appelée dès que le registre est entièrement peuplé.

  Même s’il n’est pas possible d’importer des modèles au niveau des modules où les classes `AppConfig` sont définies, il est possible de les importer dans `ready()`, en utilisant soit une instruction `import` ou `get_model()`.

  Si vous inscrivez des `signaux de modèle`, vous pouvez faire référence à l’expéditeur par son étiquette textuelle au lieu d’utiliser la classe de modèle en elle-même.

  Exemple :

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

  Avertissement

  Although you can access model classes as described above, avoid interacting with the database in your `ready()` implementation. This includes model methods that execute queries (`save()`, `delete()`, manager methods etc.), and also raw SQL queries via `django.db.connection`. Your `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

  Dans le processus d’initialisation normal, la méthode `ready` est appelée une seule fois par Django. Mais dans certains cas limites, en particulier dans les tests qui manipulent les applications installées, `ready` pourrait être appelée plus d’une fois. Dans ce cas, soit écrivez des méthodes idempotentes, soit placez un drapeau sur vos classes `AppConfig` pour empêcher de ré-exécuter le code qui ne devrait être exécuté qu’une seule fois.

### Paquets avec espace de noms en tant qu’applications

Les paquets Python sans la présence d’un fichier `__init __.py` sont appelés « paquets avec espace de noms » (namespace packages) et peuvent être dispersés dans plusieurs répertoires et à différents endroits de `sys.path` (voir PEP 420).

Les applications Django nécessitent un chemin de base unique du système de fichiers où Django (selon la configuration) recherche les gabarits, les fichiers statiques, etc. Ainsi, les paquets avec espace de noms ne peuvent être des applications Django que si l’une des conditions suivantes est vraie :

1. Le paquet avec espace de noms n’a en fait qu’un seul emplacement (c’est-à-dire qu’il n’est pas dispersé sur plus d’un répertoire).

2. La classe `AppConfig` utilisée pour configurer l’application possède un attribut de classe `path` qui correspond au chemin de répertoire absolu que Django utilise comme chemin de base unique pour l’application.

Si aucune de ces conditions n’est remplie, Django génère une exception `ImproperlyConfigured`.

## Registre d’applications

apps

  Le registre d’applications fournit l’API publique suivante. Les méthodes qui ne sont pas énumérées ci-dessous sont considérées comme privées et peuvent changer sans préavis.

apps.ready

  Attribut booléen défini à `True` après que le registre a été entièrement peuplé et que toutes les méthodes `AppConfig.ready()` ont été appelées.

apps.get_app_configs()

  Renvoie un objet itérable d’instances de `AppConfig`.

apps.get_app_config(app_label)

  Renvoie une instance `AppConfig` de l’application correspondant à `app_label`. Génère `LookupError` si une telle application n’existe pas.

apps.is_installed(app_name)

  Vérifie si une application avec le nom donné existe dans le registre. `app_name` est le nom complet de l’application, par ex. `'django.contrib.admin'`.

apps.get_model(app_label, model_name, require_ready=True)

  Renvoie la classe `Model` correspondant aux paramètres `app_label` et `model_name`. Cette méthode accepte aussi en raccourci un paramètre unique sous la forme `app_label.model_name`. `model_name` est insensible à la casse.

  Génère `LookupError` si aucune application ou modèle correspondant n’existe. Génère `ValueError` lorsque un paramètre unique est fourni sans contenir exactement un seul point.

  Nécessite que le registre des applications soit complètement défini, sauf dans le cas où le paramètre `require_ready` est `False`.

  La définition de `require_ready` à `False` permet de consulter des modèles pendant que le registre des applications est en cours de remplissage, particulièrement dans la seconde phase où les modèles sont importés. `get_model()` a donc le même effet que l’importation du modèle. Le principal cas d’utilisation concerne la configuration de classes de modèles en fonction de réglages, tels que `AUTH_USER_MODEL`.

  Lorsque `require_ready` vaut `False`, `get_model()` renvoie une classe de modèle qui peut ne pas être complètement fonctionnelle (par exemple, l’accès aux relations inversées peut être manquant) en attendant que le registre des applications soit complètement rempli. Pour cette raison, il est préférable de laisser `require_ready` à sa valeur par défaut `True` autant que possible.

## Processus d’initialisation

### Chargement des applications

When Django starts, `django.setup()` is responsible for populating the application registry.

setup(set_prefix=True)

  Configure Django en :

  - chargeant les réglages ;

  - configurant la journalisation ;

  - Si `set_prefix` vaut `True`, définissant le préfixe de script de résolution d’URL à `FORCE_SCRIPT_NAME` s’il est défini ou sinon à `/`.

  - initialisant le registre d’applications.

  Cette fonction est appelée automatiquement :

  - lors de l’exécution d’un serveur HTTP via le support ASGI ou WSGI de Django ;

  - lors de l’appel d’une commande de gestion.

  Elle doit être appelée explicitement dans d’autres cas, comme par exemple dans les scripts Python ordinaires.

Le registre d’applications est initialisé en trois étapes. À chaque étape, Django traite toutes les applications dans l’ordre de `INSTALLED_APPS`.

1. Tout d’abord, Django importe chaque élément de `INSTALLED_APPS`.

   S’il s’agit d’une classe de configuration de l’application, Django importe le paquet racine de l’application, défini par son attribut `name`. S’il s’agit d’un paquet Python, Django recherche une configuration d’application dans un sous-module `apps.py`, ou sinon crée une configuration d’application par défaut.

   À ce stade, votre code ne devrait pas importer de modèles !

   En d’autres termes, les paquets racines de vos applications et les modules qui définissent vos classes de configuration d’application ne devraient pas importer de modèles, même indirectement.

   Strictement parlant, Django permet d’importer des modèles une fois que leur configuration d’application est chargée. Toutefois, afin d’éviter toute contrainte inutile sur l’ordre dans `INSTALLED_APPS`, il est fortement recommandé de ne pas importer de modèles à ce stade.

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

2. Puis Django tente d’importer le sous-module `models` de chaque application, s’il en existe un.

   Vous devez définir ou importer tous les modèles dans les fichiers `models.py` ou `models/__init__.py` de votre application. Autrement, le registre des applications pouvant ne pas être entièrement peuplé à ce point, cela pourrait provoquer un dysfonctionnement de l’ORM.

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

3. Finally Django runs the `ready()` method of each application configuration.

### Dépannage

Voici quelques problèmes courants que vous pouvez rencontrer lors de l’initialisation :

- `AppRegistryNotReady`: cela se produit lorsque l’importation d’une configuration d’application ou d’un module de modèles exécute du code qui dépend du registre d’applications.

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

  L’exécution de requêtes en base de données avec l’ORM au moment de l’importation dans les modules de modèles déclenche également cette exception. L’ORM ne peut pas fonctionner correctement avant que tous les modèles ne soient disponibles.

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

- `ImportError: cannot import name ...` Cela se produit si la séquence d’importation se trouve être une boucle.

  Pour éliminer de tels problèmes, vous devez réduire les dépendances entre vos modules de modèles et réaliser le moins de travail possible au moment de l’importation. Pour éviter d’exécuter du code au moment de l’importation, vous pouvez le déplacer dans une fonction et mettre en cache ses résultats. Le code sera exécuté la première fois que vous aurez besoin de ses résultats. Ce concept est connu sous le nom d”« évaluation différée ».

- `django.contrib.admin` effectue automatiquement la découverte des modules `admin` dans les applications installées. Pour l’en empêcher, modifiez le réglage `INSTALLED_APPS` pour qu’il contienne `'django.contrib.admin.apps.SimpleAdminConfig'` au lieu de `'django.contrib.admin'`.

- `RuntimeWarning: Accessing the database during app initialization is discouraged.` Cet avertissement est généré par des requêtes de base de données exécutées avant que les applications ne soient prêtes, comme par exemple durant l’importation des modules ou dans la méthode `AppConfig.ready()`. De telles requêtes de base de données prématurées sont découragées car elles vont s’exécuter durant le démarrage de chaque commande d’administration, ce qui va ralentir le démarrage du projet, mettre potentiellement en cache des données obsolètes et elles peuvent même échouer si des migrations sont pendantes.

  Typiquement, une erreur courante est d’interroger la base de données pour remplir des choix de champ de formulaire :

      class LocationForm(forms.Form):
          country = forms.ChoiceField(choices=[c.name for c in Country.objects.all()])

  Dans l’exemple ci-dessus, la requête sous-jacente de `Country.objects.all()` est exécutée durant l’importation du module, car il y a itération de l’objet `QuerySet`. Pour éviter l’avertissement, le formulaire pourrait utiliser `ModelChoiceField` à la place :

      class LocationForm(forms.Form):
          country = forms.ModelChoiceField(queryset=Country.objects.all())

  Pour faciliter le repérage du code qui a généré l’avertissement, vous pouvez demander à Python de traiter les avertissements comme des erreurs pour révéler la trace d’erreur, par exemple avec `python -Werror manage.py shell`.