Django contiene un registro de aplicaciones instaladas que almacena la configuración y proporciona introspección. También mantiene una lista de modelos disponibles:doc:modelos <topics/db/models>.
Este registro se llama apps y está disponible en django.apps:
>>> from django.apps import apps
>>> apps.get_app_config("admin").verbose_name
'Administration'
El término proyecto describe una aplicación web de Django. El paquete Python del proyecto se define principalmente por un módulo de configuración, pero suele contener otras cosas. Por ejemplo, cuando ejecutas django-admin startproject mysite obtendrás un directorio de proyecto mysite que contiene un paquete Python mysite con settings.py, urls.py, asgi.py y wsgi.py. El paquete del proyecto se extiende a menudo para incluir cosas como fijaciones, CSS y plantillas que no están atadas a una aplicación en particular.
El directorio raíz de un proyecto (el que contiene manage.py) suele ser el contenedor de todas las aplicaciones del proyecto que no se instalan por separado.
El término aplicación describe un paquete Python que proporciona algún conjunto de características. Las aplicaciones pueden reutilizarse en varios proyectos.
Las aplicaciones incluyen alguna combinación de modelos, vistas, plantillas, etiquetas de plantilla, archivos estáticos, URLs, middleware, etc. Se conectan generalmente a los proyectos con la configuración INSTALLED_APPS y opcionalmente con otros mecanismos como URLconfs, la configuración MIDDLEWARE o la herencia de plantillas.
Es importante entender que una aplicación de Django es un conjunto de código que interactúa con varias partes del marco. No existe tal cosa como un objeto Application. Sin embargo, hay unos pocos lugares donde Django necesita interactuar con las aplicaciones instaladas, principalmente para la configuración y también para la introspección. Eso es por qué el registro de aplicaciones mantiene metadatos en una instancia AppConfig para cada aplicación instalada.
No hay restricciones que impidan que un paquete del proyecto no pueda considerarse también como una aplicación y tener modelos, etc. (lo que requeriría agregarlo a la configuración INSTALLED_APPS).
Para configurar una aplicación, crea un módulo apps.py dentro de la aplicación y define una subclase de AppConfig allí.
Cuando INSTALLED_APPS contiene el camino puntoado a un módulo de aplicación, por defecto, si Django encuentra exactamente una subclase de AppConfig en el módulo apps.py, utiliza esa configuración para la aplicación. Este comportamiento puede ser deshabilitado estableciendo AppConfig.default a False.
Si el módulo apps.py contiene más de una subclase de AppConfig, Django buscará una sola donde AppConfig.default es True.
Si no se encuentra ninguna subclase de AppConfig, se utilizará la clase base AppConfig.
Alternativamente, INSTALLED_APPS puede contener el camino puntoado a una clase de configuración para especificarla explícitamente:
INSTALLED_APPS = [
...,
"polls.apps.PollsAppConfig",
...,
]
Si estás utilizando «Rock “n” roll» en un proyecto llamado anthology, pero quieres que se muestre como «Jazz Manouche» en su lugar, puedes proporcionar tu propia configuración:
# 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",
# ...
]
Este ejemplo muestra clases de configuración específicas del proyecto ubicadas en un submódulo llamado apps.py. Esto es una convención y no una obligación. AppConfig las clases pueden ser definidas en cualquier lugar.
En esta situación, INSTALLED_APPS debe contener el camino punteado a la clase de configuración porque vive fuera de una aplicación y por lo tanto no puede ser detectada automáticamente.
Los objetos de configuración de la aplicación almacenan metadatos para una aplicación. Algunos atributos se pueden configurar en subclases de AppConfig. Otros son establecidos por Django y solo lectura.
Full path de Python para la aplicación, por ejemplo 'django.contrib.admin'.
Esta atributo define qué aplicación se aplica la configuración. Debe estar establecido en todas las subclases de AppConfig.
Debe ser único a lo largo de un proyecto Django.
Nombre corto para la aplicación, por ejemplo 'admin'
Este atributo permite relabelizar una aplicación cuando dos aplicaciones tienen etiquetas en conflicto. Por defecto es el último componente de name. Debe ser un identificador válido de Python.
Debe ser único a lo largo de un proyecto Django.
Advertencia
Cambiar este atributo después de que se hayan aplicado las migraciones para una aplicación dará lugar a cambios disruptivos en un proyecto o, en el caso de una app reutilizable, cualquier instalación existente de esa app. Esto es porque AppConfig.label se utiliza en tablas de bases de datos y archivos de migración cuando se hace referencia a la app en la lista de dependencias.
Nombre legible por humanos para la aplicación, por ejemplo «Administración».
Este atributo tiene un valor por defecto de label.title().
Ruta del sistema de archivos a la carpeta de la aplicación, por ejemplo '/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'.
En la mayoría de los casos, Django puede detectar y establecer automáticamente esto, pero también puedes proporcionar una sobrescritura explícita como un atributo de clase en tu subclase de AppConfig. En algunas situaciones se requiere; por ejemplo si el paquete de app es un paquete de nombre espacio con múltiples rutas.
Seteá esta atributo a False para evitar que Django seleccione automáticamente una clase de configuración. Esto es útil cuando apps.py define solo una subclase AppConfig pero no quieres que Django la utilice por defecto.
Seteá esta atributo a True para indicarle a Django que seleccione automáticamente una clase de configuración. Esto es útil cuando apps.py define más de una subclase AppConfig y quieres que Django utilice alguna de ellas por defecto.
Por defecto, esta atributo no está establecido.
El tipo de clave primaria implícito para agregar a los modelos dentro de esta aplicación. Puedes utilizar esto para mantener el tipo de clave primaria como AutoField para aplicaciones de terceros.
Por defecto, este valor es el de la variable de entorno DEFAULT_AUTO_FIELD.
Módulo raíz de la aplicación, por ejemplo <module 'django.contrib.admin' from 'django/contrib/admin/__init__.py'>.
Módulo que contiene los modelos, por ejemplo <module 'django.contrib.admin.models' from 'django/contrib/admin/models.py'>.
Puede ser None si la aplicación no contiene un módulo de modelos. Ten en cuenta que solo se emiten señales relacionadas con la base de datos como pre_migrate y post_migrate para aplicaciones que tienen un módulo de modelos.
Returns an iterable de clases Model para esta aplicación.
Requiere que el registro de la app esté completamente poblado.
Devuelve la clase Model con el nombre dado model_name. model_name es insensible a mayúsculas y minúsculas.
Lanza una LookupError si no existe tal modelo en esta aplicación.
Requiere que el registro de la app esté completamente poblado a menos que se establezca el argumento require_ready en False. require_ready comporta exactamente como en apps.get_model().
Las subclases pueden sobreescribir este método para realizar tareas de inicialización, como registrar señales. Se llama tan pronto como el registro esté completamente poblado.
Aunque no puedes importar modelos a nivel de módulo donde se definen las clases AppConfig, sí puedes importarlos en ready(), utilizando una sentencia import o la método get_model().
Si estás registrando señales de modelo (model signals), puedes referirte al emisor por su etiqueta de cadena en lugar de utilizar la clase del modelo mismo.
Ejemplo:
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")
Advertencia
Aunque puedes acceder a las clases de modelos como se describe arriba, evita interactuar con la base de datos en tu implementación de ready(). Esto incluye métodos de modelo que ejecutan consultas (save(), delete(), métodos de gestor, etc.), y también consultas SQL crudas a través de django.db.connection. Tu método ready() se ejecutará durante el arranque de cada comando de administración. Por ejemplo, aunque la configuración de base de datos de prueba está separada de las configuraciones de producción, manage.py test aún ejecutaría algunas consultas contra tu base de datos de producción!
Nota
En el proceso de inicialización habitual, el método ready se llama solo una vez por Django. Pero en algunos casos de esquina, particularmente en pruebas que están manipulando aplicaciones instaladas, ready podría llamarse más de una vez. En ese caso, escriba métodos idempotentes o ponga una bandera en las clases de configuración AppConfig para evitar ejecutar código que debe ejecutarse exactamente una vez.
Los paquetes Python sin un archivo __init__.py son conocidos como «paquetes de nombres» y pueden estar dispersos en múltiples directorios en diferentes ubicaciones en sys.path (consulte PEP 420).
Las aplicaciones de Django requieren una sola ruta de sistema de archivos base donde Django (dependiendo de la configuración) buscará plantillas, activos estáticos, etc. Por lo tanto, los paquetes de nombres solo pueden ser aplicaciones de Django si se cumple uno de los siguientes:
El paquete de nombres en realidad tiene solo una ubicación (es decir, no está disperso en más de un directorio).
La clase AppConfig utilizada para configurar la aplicación tiene un atributo de clase path, que es el directorio absoluto que Django utilizará como ruta base única para la aplicación.
Si ninguna de estas condiciones se cumple, Django levantará una excepción ImproperlyConfigured.
El registro de aplicaciones proporciona la siguiente API pública. Los métodos que no están listados a continuación se consideran privados y pueden cambiar sin previo aviso.
Atributo booleano que se establece en True después de que el registro esté completamente poblado y todos los métodos AppConfig.ready() se hayan llamado.
Returns a AppConfig para la aplicación con el app_label dado. Levanta una LookupError si no existe tal aplicación.
Verifica si existe una aplicación con el nombre dado en el registro. app_name es el nombre completo de la app, por ejemplo 'django.contrib.admin'.
Returns el Model con los app_label y model_name dados. Como atajo, este método también acepta un solo argumento en la forma app_label.model_name. model_name es case-insensitive.
Levanta una LookupError si no existe tal aplicación o modelo. Levanta una ValueError cuando se llama con un solo argumento que no contiene exactamente un punto.
Requiere que el registro de aplicaciones esté completamente poblado a menos que el argumento require_ready esté establecido en False.
Establecer require_ready en False permite buscar modelos mientras se está poblando el registro de aplicaciones, específicamente durante la segunda fase donde importa modelos. Luego get_model() tiene el mismo efecto que importar el modelo. El caso de uso principal es configurar clases de modelo con ajustes, como AUTH_USER_MODEL.
Cuando require_ready es False, get_model() devuelve una clase de modelo que puede no estar completamente funcional (los accesores inversos pueden faltar, por ejemplo) hasta que el registro de aplicaciones esté completamente poblado. Por esta razón, es mejor dejar require_ready en su valor predeterminado de True siempre que sea posible.
Cuando Django arranca, django.setup() es responsable de poblar el registro de aplicaciones.
Configura Django por:
Carga las configuraciones.
Establece la configuración de registro.
Si set_prefix es Verdadero, establece el prefijo del script resolutor de URL a FORCE_SCRIPT_NAME si está definido, o / en caso contrario.
Inicia el registro de aplicaciones.
Esta función se llama automáticamente:
Cuando se ejecuta un servidor HTTP mediante el soporte ASGI o WSGI de Django.
Cuando invocas una orden de comando de administración.
Debes llamarla explícitamente en otros casos, por ejemplo, en scripts Python puros.
La aplicación de registro se inicia en tres etapas. En cada etapa, Django procesa todas las aplicaciones en el orden de INSTALLED_APPS.
Django importa primero cada elemento en INSTALLED_APPS.
Si es una clase de configuración de aplicación, Django importa el paquete raíz de la aplicación, definido por su atributo name. Si es un paquete Python, Django busca una configuración de aplicación en un módulo apps.py submódulo o crea una configuración de aplicación predeterminada.
En esta etapa, tu código no debe importar modelos.
En otras palabras, los paquetes raíz de tus aplicaciones y los módulos que definen las clases de configuración de aplicación no deben importar modelos, ni de manera indirecta.
Hasta cierto punto, Django permite importar modelos una vez que se carga la configuración de aplicación. Sin embargo, para evitar restricciones innecesarias en el orden de INSTALLED_APPS, se recomienda fuertemente no importar ningún modelo en esta etapa.
Una vez que complete esta etapa, las APIs que operan sobre configuraciones de aplicaciones como get_app_config() se vuelven utilizables.
Luego Django intenta importar el módulo models de cada aplicación, si existe uno.
Debes definir o importar todos los modelos en tu archivo models.py o models/__init__.py. De lo contrario, el registro de aplicaciones puede no estar completamente poblado en este punto, lo que podría causar que la ORM se malogre.
Una vez que complete esta etapa, las APIs que operan sobre modelos como get_model() se vuelven utilizables.
Finalmente Django ejecuta el método ready() de cada configuración de aplicación.
Aquí tienes algunos problemas comunes que podrías encontrar durante la inicialización:
AppRegistryNotReady: Esto sucede cuando importar una configuración de aplicación o un módulo de modelos desencadena código que depende del registro de aplicaciones.
Por ejemplo, gettext() utiliza el registro de aplicaciones para buscar catálogos de traducciones en las aplicaciones. Para traducir al tiempo de importación, debes usar gettext_lazy() en su lugar. (Usar gettext() sería un error, porque la traducción ocurriría al tiempo de importación, en lugar de cada vez que se realice una solicitud dependiendo del idioma activo.)
Ejecutar consultas a la base de datos con el ORM en el tiempo de importación en módulos de modelos también desencadenará esta excepción. El ORM no puede funcionar correctamente hasta que todos los modelos estén disponibles.
Esta excepción también sucede si olvidas llamar a django.setup() en un script Python independiente.
ImportError: cannot import name ... Esto sucede si la secuencia de importación acaba en un bucle.
Para eliminar tales problemas, debes minimizar las dependencias entre tus módulos de modelos y hacer lo menos posible al tiempo de importación. Para evitar ejecutar código al tiempo de importación, puedes moverlo a una función y cachear sus resultados. El código se ejecutará cuando primero necesites sus resultados. Este concepto se conoce como «evaluación relajada».
django.contrib.admin realiza automáticamente la autodiscovery de módulos admin en aplicaciones instaladas. Para evitarlo, cambia tu INSTALLED_APPS para que contenga 'django.contrib.admin.apps.SimpleAdminConfig' en lugar de 'django.contrib.admin'.
``Advertencia de tiempo de ejecución: Se desaconseja acceder a la base de datos durante la inicialización de la aplicación.` Esta advertencia se desencadena por consultas a la base de datos ejecutadas antes de que las aplicaciones estén listas, como durante los importes de módulos o en el método AppConfig.ready(). Tales consultas prematuras a la base de datos se desaconsejan porque se ejecutarán durante el arranque de cada comando de gestión, lo que ralentizará el arranque del proyecto, puede incluso hacer que se cacheen datos caducados y puede fallar si hay migraciones pendientes.
Por ejemplo, un error común es realizar una consulta a la base de datos para poblar las opciones de campo de formulario:
class LocationForm(forms.Form):
country = forms.ChoiceField(choices=[c.name for c in Country.objects.all()])
En el ejemplo anterior, la consulta desde Country.objects.all() se ejecuta durante el importe del módulo porque se itera sobre el conjunto de consultas. Para evitar la advertencia, el formulario podría utilizar en su lugar un ModelChoiceField:
class LocationForm(forms.Form):
country = forms.ModelChoiceField(queryset=Country.objects.all())
Para hacer que sea más fácil encontrar el código que desencadenó esta advertencia, puedes hacer que Python trate las advertencias como errores para revelar la pila de llamadas, por ejemplo con python -Werror manage.py shell.
may 31, 2026