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 tout simplement 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
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 nâest quâ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, héritez de AppConfig
et placez le chemin de cette sous-classe avec la syntaxe pointée dans INSTALLED_APPS
.
Lorsque INSTALLED_APPS
contient simplement le chemin vers un module dâapplication avec la syntaxe pointĂ©e, Django recherche une variable default_app_config
dans ce module.
Si elle est dĂ©finie, il sâagit du chemin en syntaxe pointĂ©e vers la sous-classe de AppConfig
pour cette application.
Sâil nây a pas de default_app_config
, Django utilise la classe de base AppConfig
.
default_app_config
permet aux applications créées avant Django 1.7 telles que django.contrib.admin
de faire la transition vers la fonctionnalité AppConfig
sans exiger des utilisateurs quâils mettent Ă jour leur rĂ©glage INSTALLED_APPS
.
Les nouvelles applications devraient éviter default_app_config
. Elles devraient plutÎt exiger le chemin pointé vers la sous-classe AppConfig
appropriée de maniÚre explicite dans le réglage INSTALLED_APPS
.
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"
Vous pouvez faire en sorte que votre application charge cette sous-classe de AppConfig
par défaut comme cela :
# rock_n_roll/__init__.py
default_app_config = 'rock_n_roll.apps.RockNRollConfig'
Cela entraĂźne lâutilisation de RockNRollConfig
lorsque INSTALLED_APPS
contient seulement 'rock_n_roll'
. Cela permet dâutiliser les fonctionnalitĂ©s de AppConfig
sans exiger des utilisateurs quâils mettent Ă jour leur rĂ©glage INSTALLED_APPS
. En dehors de ce cas dâutilisation, il est prĂ©fĂ©rable dâĂ©viter lâutilisation de default_app_config
mais de plutĂŽt indiquer la classe de configuration dâapplication dans INSTALLED_APPS
comme expliqué ci-aprÚs.
Bien entendu, vous pouvez aussi dire Ă vos utilisateurs de mettre 'rock_n_roll.apps.RockNRollConfig'
dans leur réglage INSTALLED_APPS
. Vous pouvez mĂȘme fournir plusieurs sous-classes de AppConfig
diffĂ©rentes avec des comportements diffĂ©rents et permettre aux utilisateurs dâen choisir une via leur rĂ©glage INSTALLED_APPS
.
La convention recommandĂ©e est de mettre la classe de configuration dans un sous-module de lâapplication nommĂ© apps
. Cependant, ce nâest pas requis par Django.
Vous devez inclure lâattribut name
pour que Django puisse dĂ©terminer Ă quelle application cette configuration sâapplique. Vous pouvez dĂ©finir nâimporte quel attribut documentĂ© dans la rĂ©fĂ©rence de lâAPI de AppConfig
.
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',
# ...
]
Encore une fois, la définition de classes de configuration spécifiques au projet dans un sous-module appelé apps
est une convention, pas une obligation.
Configuration dâapplications¶
-
class
AppConfig
[source]¶ 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 dename
. Il doit ĂȘtre un identifiant Python valide.Il doit ĂȘtre unique dans le contexte dâun mĂȘme projet Django.
-
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.
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 modulemodels
. Notez que les signaux relatifs à la base de données tels quepre_migrate
etpost_migrate
ne sont émis que pour les applications qui ont un modulemodels
.
Méthodes¶
-
AppConfig.
get_models
()[source]¶ 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)[source]¶ Renvoie la classe
Model
ayant le nommodel_name
donné.model_name
est insensible à la casse.GénÚre
LookupError
si aucun modĂšle de ce nom nâexiste dans cette application.NĂ©cessite que le registre des applications soit complĂštement dĂ©fini, sauf dans le cas oĂč le paramĂštre
require_ready
estFalse
.require_ready
a le mĂȘme comportement que pourapps.get_model()
.
-
AppConfig.
ready
()[source]¶ 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 dansready()
, en utilisant soit une instructionimport
ouget_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.db.models.signals import pre_save 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
Bien que vous puissiez accĂ©der aux classes de modĂšles comme expliquĂ© ci-dessus, Ă©vitez dâinteragir avec la base de donnĂ©es dans lâimplĂ©mentation de
ready()
. Ceci inclut les mĂ©thodes de modĂšles qui exĂ©cutent des requĂȘtes (save()
,delete()
, les mĂ©thodes de gestionnaires de modĂšles, etc.), ainsi que les requĂȘtes SQL brutes viadjango.db.connection
. La méthodeready()
sâexĂ©cute lors du dĂ©marrage de chaque commande de gestion. Par exemple, bien que la configuration de la base de donnĂ©es de test soit sĂ©parĂ©e des rĂ©glages de production,manage.py test
pourrait malgrĂ© tout exĂ©cuter des requĂȘtes sur votre base de donnĂ©es de production !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 classesAppConfig
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 :
- 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).
- La classe
AppConfig
utilisĂ©e pour configurer lâapplication possĂšde un attribut de classepath
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éthodesAppConfig.ready()
ont été appelées.
-
apps.
get_app_config
(app_label)¶ Renvoie une instance
AppConfig
de lâapplication correspondant Ăapp_label
. GénÚreLookupError
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Ăštresapp_label
etmodel_name
. Cette méthode accepte aussi en raccourci un paramÚtre unique sous la formeapp_label.model_name
.model_name
est insensible à la casse.GénÚre
LookupError
si aucune application ou modĂšle correspondant nâexiste. GĂ©nĂšreValueError
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
estFalse
.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 queAUTH_USER_MODEL
.Lorsque
require_ready
vautFalse
,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 laisserrequire_ready
à sa valeur par défautTrue
autant que possible.
Processus dâinitialisation¶
Chargement des applications¶
Lorsque Django démarre, django.setup()
est responsable de peupler le registre des applications.
-
setup
(set_prefix=True)[source]¶ Configure Django en :
- chargeant les réglages ;
- configurant la journalisation ;
- Si
set_prefix
vautTrue
, 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 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
.
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 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.Une fois cette Ă©tape terminĂ©e, les API qui exploitent les configurations dâapplication telles que
get_app_config()
deviennent utilisables.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
oumodels/__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.Une fois cette Ă©tape terminĂ©e, les API qui agissent sur des modĂšles telles que
get_model()
deviennent utilisables.Enfin, Django exécute la méthode
ready()
de chaque configuration dâapplication.
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.Par exemple,
gettext()
utilise le registre dâapplications pour rechercher des catalogues de traduction dans les applications. Pour traduire au moment de lâimportation, vous devez utilisergettext_lazy()
Ă la place (lâutilisation degettext()
serait une erreur, parce que la traduction sâeffectuerait au moment de lâimportation plutĂŽt quâĂ chaque requĂȘte en fonction de la langue active).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.
Cette exception se produit Ă©galement si vous oubliez dâappeler
django.setup()
dans un script Python autonome.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 modulesadmin
dans les applications installĂ©es. Pour lâen empĂȘcher, modifiez le rĂ©glageINSTALLED_APPS
pour quâil contienne'django.contrib.admin.apps.SimpleAdminConfig'
au lieu de'django.contrib.admin'
.