Django contiene un registro de aplicaciones instaladas que almacena la configuración y proporciona introspección. También mantiene una lista de disponibles modelos.

Este registro se llama apps y está disponible en django.apps:

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

Proyectos y aplicaciones

El término proyecto describe una aplicación web de Django. El paquete Python del proyecto se define principalmente mediante un módulo de configuración, pero generalmente contiene otras cosas. Por ejemplo, cuando corres django-admin startproject mysite obtendrás un mysite directorio del proyecto que contiene un mysite Paquete de Python con settings.py, urls.py, asgi.py y wsgi.py. El paquete del proyecto a menudo se amplía para incluir elementos como accesorios, CSS y plantillas que no están vinculados a una aplicación en particular.

A directorio raíz del proyecto (el que contiene manage.py) suele ser el contenedor de todas las aplicaciones de un proyecto que no se instalan por separado.

El término solicitud describe un paquete de Python que proporciona un conjunto de características. Aplicaciones puede ser reutilizado en varios proyectos.

Las aplicaciones incluyen alguna combinación de modelos, vistas, plantillas, etiquetas de plantilla, static archivos, URL, middleware, etc. Por lo general, están conectados a proyectos con la INSTALLED_APPS configuración y opcionalmente con otros mecanismos como URLconfs, el MIDDLEWARE configuración o herencia de plantilla.

Es importante comprender que una aplicación Django es un conjunto de código que interactúa con varias partes del marco. No existe tal cosa como un Application objeto. Sin embargo, hay algunos lugares donde Django necesita interactuar con las aplicaciones instaladas, principalmente para la configuración y también para la introspección. Es por eso que el registro de la aplicación mantiene los metadatos en un AppConfig instancia para cada aplicación instalada.

No hay ninguna restricción de que un paquete de proyecto no pueda considerarse una aplicación y tener modelos, etc. (lo que requeriría agregarlo a INSTALLED_APPS).

Configurando aplicaciones

Para configurar una aplicación, cree una apps.py módulo dentro de la aplicación, luego defina una subclase de AppConfig allí.

Cuando INSTALLED_APPS contiene la ruta de puntos a un módulo de aplicación, por defecto, si Django encuentra exactamente uno AppConfig subclase en el apps.py submódulo, utiliza esa configuración para la aplicación. Este comportamiento se puede deshabilitar configurando AppConfig.default para False.

Si el apps.py el módulo contiene más de uno AppConfig subclase, Django buscará una sola donde AppConfig.default es True.

Si no AppConfig se encuentra la subclase, la base AppConfig se utilizará la clase.

Alternativamente, INSTALLED_APPS puede contener la ruta de puntos a una clase de configuración para especificarla explícitamente:

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

Para autores de aplicaciones

Si está creando una aplicación conectable llamada “Rock ‘n’ roll”, así es como debe proporcionar un nombre propio para el administrador:

# rock_n_roll/apps.pyfrom django.apps import AppConfig

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

RockNRollConfig se cargará automáticamente cuando INSTALLED_APPS contiene 'rock_n_roll'. Si necesita evitar esto, configure default para False en la definición de clase.

Puede proporcionar varios AppConfig subclases con diferentes comportamientos. Para decirle a Django cuál usar por defecto, configure default para True en su definición. Si sus usuarios desean elegir una configuración no predeterminada, deben reemplazar 'rock_n_roll' con la ruta de puntos a esa clase específica en su INSTALLED_APPS configuración.

los AppConfig.name attribute le dice a Django a qué aplicación se aplica esta configuración. Puedes definir cualquier otro attribute documentado en el AppConfig Referencia de API.

AppConfig las subclases se pueden definir en cualquier lugar. los apps.py la convención simplemente permite que Django los cargue automáticamente cuando INSTALLED_APPS contiene la ruta a un módulo de aplicación en lugar de la ruta a una clase de configuración.

Nota

Si su código importa el registro de la aplicación en el __init__.py, el nombre apps Chocará con el apps submódulo. La mejor práctica es mover ese código a un submódulo e importarlo. Una solución alternativa es importar el registro con un nombre diferente:

from django.apps import apps as django_apps

Cambiado en Django 3.2:

En versiones anteriores, un default_app_config La variable en el módulo de la aplicación se utilizó para identificar la clase de configuración de la aplicación predeterminada.

Para usuarios de aplicaciones

Si usa “Rock ‘n’ roll” en un proyecto llamado anthology, pero desea que se muestre como “Jazz Manouche”, puede proporcionar su propia configuración:

# anthology/apps.pyfrom rock_n_roll.apps import RockNRollConfig

classJazzManoucheConfig(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. Esta es una convención, no un requisito. AppConfig las subclases se pueden definir en cualquier lugar.

En esta situación, INSTALLED_APPS debe contener la ruta de puntos a la clase de configuración porque vive fuera de una aplicación y, por lo tanto, no se puede detectar automáticamente.

Configuración de la aplicación

class AppConfig

Los objetos de configuración de la aplicación almacenan metadatos para una aplicación. Algunos attributes se puede configurar en AppConfig subclases. Otros están configurados por Django y son de solo lectura.

Configurable attributes

AppConfig.name

Ruta completa de Python a la aplicación, p. Ej. 'django.contrib.admin'.

Esta attribute define a qué aplicación se aplica la configuración. Debe estar configurado en todos AppConfig subclases.

Debe ser único en un proyecto de Django.

AppConfig.label

Nombre corto de la aplicación, p. Ej. 'admin'

Esta attribute permite volver a etiquetar una aplicación cuando dos aplicaciones tienen etiquetas en conflicto. Por defecto, el último componente de name. Debe ser un identificador de Python válido.

Debe ser único en un proyecto de Django.

AppConfig.verbose_name

Nombre legible por humanos para la aplicación, por ejemplo, “Administración”.

Esta attribute predeterminado a label.title().

AppConfig.path

Ruta del sistema de archivos al directorio de la aplicación, p. Ej. '/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'.

En la mayoría de los casos, Django puede detectar y configurar esto automáticamente, pero también puede proporcionar una anulación explícita como clase attribute en tu AppConfig subclase. En algunas situaciones esto es necesario; por ejemplo, si el paquete de la aplicación es un paquete de espacio de nombres con múltiples rutas.

AppConfig.default
Nuevo en Django 3.2.

Establecer esto attribute para False para evitar que Django seleccione una clase de configuración automáticamente. Esto es útil cuando apps.py define solo uno AppConfig subclase pero no quieres que Django lo use por defecto.

Establecer esto attribute para True para decirle a Django que seleccione una clase de configuración automáticamente. Esto es útil cuando apps.py define más de uno AppConfig subclase y desea que Django use uno de ellos por defecto.

Por defecto, este attribute no está configurado.

AppConfig.default_auto_field
Nuevo en Django 3.2.

El primario implícito key escriba para agregar a los modelos dentro de esta aplicación. Puedes usar esto para mantener AutoField como el principal key tipo para aplicaciones de terceros.

Por defecto, este es el valor de DEFAULT_AUTO_FIELD.

Solo lectura attributes

AppConfig.module

Módulo raíz para la aplicación, p. Ej. .

AppConfig.models_module

Módulo que contiene los modelos, p. Ej. .

Puede ser None si la aplicación no contiene un models módulo. Tenga en cuenta que las señales relacionadas con la base de datos, como pre_migrate y post_migrate solo se emiten para aplicaciones que tienen un models módulo.

Métodos

AppConfig.get_models()

Devuelve un iterable de Model clases para esta aplicación.

Requiere que el registro de la aplicación esté completo.

AppConfig.get_model(model_name, require_ready=True)

Devuelve el Model con lo dado model_name. model_name no distingue entre mayúsculas y minúsculas.

Eleva LookupError si no existe tal modelo en esta aplicación.

Requiere que el registro de la aplicación esté completo a menos que el require_ready el argumento se establece en False. require_ready se comporta exactamente como en apps.get_model().

AppConfig.ready()

Las subclases pueden anular este método para realizar tareas de inicialización, como registrar señales. Se llama tan pronto como el registro se llena por completo.

Aunque no puede importar modelos a nivel de módulo donde AppConfig las clases están definidas, puede importarlas en ready(), usando un import declaración o get_model().

Si te estas registrando model signals, puede referirse al remitente por su string etiqueta en lugar de utilizar la clase de modelo en sí.

Ejemplo:

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


classRockNRollConfig(AppConfig):# ...defready(self):# importing model classesfrom.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 puede acceder a las clases de modelo como se describe anteriormente, evite interactuar con la base de datos en su ready() implementación. Esto incluye métodos de modelo que ejecutan consultas (save(), delete(), métodos de administrador, etc.), y también consultas SQL sin procesar a través de django.db.connection. Tu ready() El método se ejecutará durante el inicio de cada comando de administración. Por ejemplo, aunque la configuración de la base de datos de prueba es independiente de la configuración de producción, manage.py test todavía ejecutaría algunas consultas contra su producción ¡base de datos!

Nota

En el proceso de inicialización habitual, el ready Django solo llama una vez al método. Pero en algunos casos de esquina, particularmente en pruebas que están jugando con las aplicaciones instaladas, ready podría llamarse más de una vez. En ese caso, escriba métodos idempotentes o coloque una bandera en su AppConfig clases para evitar que se vuelva a ejecutar el código que debe ejecutarse exactamente una vez.

Paquetes de espacio de nombres como aplicaciones

Paquetes de Python sin __init__.py Los archivos se conocen como “paquetes de espacio de nombres” y pueden estar distribuidos en varios directorios en diferentes ubicaciones en sys.path (ver PEP 420).

Las aplicaciones de Django requieren una ruta de sistema de archivos base única donde Django (dependiendo de la configuración) buscará plantillas, static activos, etc. Por lo tanto, los paquetes de espacio de nombres solo pueden ser aplicaciones de Django si uno de los siguientes es true:

  1. El paquete de espacio de nombres en realidad tiene una única ubicación (es decir, no se distribuye en más de un directorio).
  2. los AppConfig La clase utilizada para configurar la aplicación tiene una path clase attribute, que es la ruta de directorio absoluta que Django usará como ruta de base única para la aplicación.

Si no se cumple ninguna de estas condiciones, Django aumentará ImproperlyConfigured.

Registro de aplicaciones

apps

El registro de la aplicación proporciona la siguiente API pública. Los métodos que no se enumeran a continuación se consideran privados y pueden cambiar sin previo aviso.

apps.ready

Booleano attribute que está configurado para True después de que el registro esté completamente poblado y todo AppConfig.ready() se llaman métodos.

apps.get_app_configs()

Devuelve un iterable de AppConfig instancias.

apps.get_app_config(app_label)

Devuelve un AppConfig para la aplicación con el dado app_label. Eleva LookupError si no existe tal aplicación.

apps.is_installed(app_name)

Comprueba si existe una aplicación con el nombre de pila en el registro. app_name es el nombre completo de la aplicación, p. ej. 'django.contrib.admin'.

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

Devuelve el Model con lo dado app_label y model_name. Como atajo, este método también acepta un solo argumento en el formulario app_label.model_name. model_name no distingue entre mayúsculas y minúsculas.

Eleva LookupError si no existe tal aplicación o modelo. Eleva ValueError cuando se llama con un solo argumento que no contiene exactamente un punto.

Requiere que el registro de la aplicación esté completo a menos que el require_ready el argumento se establece en False.

Configuración require_ready para False permite buscar modelos mientras se completa el registro de la aplicación, concretamente 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 ser completamente funcional (por ejemplo, pueden faltar los accesos inversos) hasta que el registro de la aplicación esté completamente lleno. Por eso es mejor irse require_ready al valor predeterminado de True cuando sea posible.

Proceso de inicialización

Cómo se cargan las aplicaciones

Cuando comienza Django, django.setup() es responsable de completar el registro de la aplicación.

setup(set_prefix=True)[source]

Configura Django por:

  • Cargando la configuración.
  • Configuración de registro.
  • Si set_prefix es Verdadero, configurando la secuencia de comandos de resolución de URL prefix para FORCE_SCRIPT_NAME si está definido, o / de lo contrario.
  • Inicializando el registro de la aplicación.

Esta función se llama automáticamente:

  • Cuando se ejecuta un servidor HTTP a través del soporte WSGI de Django.
  • Al invocar un comando de gestión.

Debe llamarse explícitamente en otros casos, por ejemplo, en scripts simples de Python.

El registro de la aplicación se inicializa en tres etapas. En cada etapa, Django procesa todas las aplicaciones en el orden de INSTALLED_APPS.

  1. Primero, Django importa cada elemento en INSTALLED_APPS.

    Si es una clase de configuración de la aplicación, Django importa el paquete raíz de la aplicación, definido por su name attribute. Si es un paquete de Python, Django busca una configuración de aplicación en un apps.py submódulo, o bien crea una configuración de aplicación predeterminada.

    En esta etapa, su código no debería importar ningún modelo.

    En otras palabras, los paquetes raíz de sus aplicaciones y los módulos que definen las clases de configuración de su aplicación no deberían importar ningún modelo, ni siquiera indirectamente.

    Estrictamente hablando, Django permite importar modelos una vez cargada la configuración de su aplicación. Sin embargo, para evitar restricciones innecesarias en el orden de INSTALLED_APPS, se recomienda encarecidamente no importar ningún modelo en esta etapa.

    Una vez que se completa esta etapa, las API que operan en configuraciones de aplicaciones como get_app_config() volverse utilizable.

  2. Entonces Django intenta importar el models submódulo de cada aplicación, si existe.

    Debe definir o importar todos los modelos en la aplicación models.py o models/__init__.py. De lo contrario, es posible que el registro de la aplicación no esté completo en este punto, lo que podría provocar un mal funcionamiento del ORM.

    Una vez que se completa esta etapa, las API que operan en modelos como get_model() volverse utilizable.

  3. Finalmente Django ejecuta el ready() método de configuración de cada aplicación.

Solución de problemas

A continuación, se muestran algunos problemas comunes que puede encontrar durante la inicialización:

  • AppRegistryNotReady: Esto sucede cuando la importación de una configuración de aplicación o un módulo de modelos activa un código que depende del registro de la aplicación.

    Por ejemplo, gettext() utiliza el registro de la aplicación para buscar catálogos de traducción en las aplicaciones. Para traducir en el momento de la importación, necesita gettext_lazy() en lugar de. (Utilizando gettext() sería un error, porque la traducción se produciría en el momento de la importación, en lugar de en cada solicitud, según el idioma activo).

    La ejecución de consultas a la base de datos con el ORM en el momento de la importación en los módulos de modelos también activará esta excepción. El ORM no puede funcionar correctamente hasta que todos los modelos estén disponibles.

    Esta excepción también ocurre si olvida llamar django.setup() en una secuencia de comandos de Python independiente.

  • ImportError: cannot import name ... Esto sucede si la secuencia de importación termina en un bucle.

    Para eliminar estos problemas, debe minimizar las dependencias entre los módulos de sus modelos y hacer el menor trabajo posible en el momento de la importación. Para evitar ejecutar código en el momento de la importación, puede moverlo a una función y almacenar en caché sus resultados. El código se ejecutará cuando necesite sus resultados por primera vez. Este concepto se conoce como “evaluación perezosa”.

  • django.contrib.admin realiza automáticamente el descubrimiento automático de admin módulos en aplicaciones instaladas. Para evitarlo, cambie su INSTALLED_APPS contener 'django.contrib.admin.apps.SimpleAdminConfig' en lugar de 'django.contrib.admin'.