Este grupo redactor ha estado mucho tiempo investigando para dar resolución a tu pregunta, te regalamos la resolución de modo que deseamos que resulte de gran apoyo.
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 cuandoapps.py
define solo unoAppConfig
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 cuandoapps.py
define más de unoAppConfig
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 unmodels
módulo. Tenga en cuenta que las señales relacionadas con la base de datos, comopre_migrate
ypost_migrate
solo se emiten para aplicaciones que tienen unmodels
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 dadomodel_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 enFalse
.require_ready
se comporta exactamente como enapps.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 enready()
, usando unimport
declaración oget_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 dedjango.db.connection
. Tuready()
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 suAppConfig
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:
- El paquete de espacio de nombres en realidad tiene una única ubicación (es decir, no se distribuye en más de un directorio).
- los
AppConfig
La clase utilizada para configurar la aplicación tiene unapath
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 todoAppConfig.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 dadoapp_label
. ElevaLookupError
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 dadoapp_label
ymodel_name
. Como atajo, este método también acepta un solo argumento en el formularioapp_label.model_name
.model_name
no distingue entre mayúsculas y minúsculas.Eleva
LookupError
si no existe tal aplicación o modelo. ElevaValueError
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 enFalse
.Configuración
require_ready
paraFalse
permite buscar modelos mientras se completa el registro de la aplicación, concretamente durante la segunda fase donde importa modelos. Luegoget_model()
tiene el mismo efecto que importar el modelo. El caso de uso principal es configurar clases de modelo con ajustes, comoAUTH_USER_MODEL
.Cuando
require_ready
esFalse
,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 irserequire_ready
al valor predeterminado deTrue
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 paraFORCE_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
.
-
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 unapps.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. -
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
omodels/__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. - 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, necesitagettext_lazy()
en lugar de. (Utilizandogettext()
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 deadmin
módulos en aplicaciones instaladas. Para evitarlo, cambie suINSTALLED_APPS
contener'django.contrib.admin.apps.SimpleAdminConfig'
en lugar de'django.contrib.admin'
.
Te mostramos las reseñas y valoraciones de los lectores
Si tienes algún duda y capacidad de beneficiar nuestro tutorial eres capaz de ejecutar una crítica y con mucho gusto lo ojearemos.