Aplicações¶
Django contém um registro de aplicações instaladas que armazena configuração e fornece introspecção. Ele também mantem uma lista de modelos </topics/db/models disponíveis.
Esse registro é chamado de apps
e está disponível em django.apps
:
>>> from django.apps import apps
>>> apps.get_app_config('admin').verbose_name
'Administration'
Projetos e aplicações¶
O termo project descreve uma aplicação web Django. O pacote de projeto Python é definido primariamente por um módulo de configuração, que geralmente contêm outras coisas. Por exemplo, quando você executa django-admin startproject mysite
você criará um diretório de projeto mysite
que contêm o pacote Python mysite
com os módulos settings.py
, urls.py
, e wsgi.py
. O pacote do projeto geralmente é extendido para incluir outras coisas como fixtures, CSS e templates que não estão atrelados à nenhuma aplicação em particular.
O project’s root directory (aquele que contêm manage.py
) é geralmente o container de todas as aplicações do projeto que não estão instaladas separadamente.
O termo application descreve um pacote Python que prove alguns conjunto de recursos. Aplicativos devem ser reutilizados em projetos diferentes.
Aplicações abrigam combinações de modelos, views, templates, templates tags, static files, URLs, middleware, etc. Estas são comumente ligados ao projeto na definição INSTALLED_APPS
e opcionalmente em outros mecanismos como URLconfs, a definição MIDDLEWARE
, ou por herança de templates.
É importante entender que uma aplicação Django é apenas um conjunto de código que interage com várias partes do framework. Não existe um objeto Application
propriamente dito. Entretanto, existem alguns lugares onde o Django precisa interagir com estas aplicações instaladas, geralmente para configuração e introspecção. É por isso que o registro de aplicações mantém os metadados em uma instância AppConfig
para cada aplicação instalada.
Não existe nenhuma restrição que defina que um pacote de projeto não possa ser considerado uma aplicação e tenha seus próprios modelos, etc. (seria necessário adicionar a INSTALLED_APPS
).
Configurandos as aplicações¶
To configure an application, create an apps.py
module inside the
application, then define a subclass of AppConfig
there.
When INSTALLED_APPS
contains the dotted path to an application
module, by default, if Django finds exactly one AppConfig
subclass in
the apps.py
submodule, it uses that configuration for the application. This
behavior may be disabled by setting AppConfig.default
to False
.
If the apps.py
module contains more than one AppConfig
subclass,
Django will look for a single one where AppConfig.default
is True
.
Se a subclasse AppConfig
não for encontrada, a classe base AppConfig
será usada.
Alternatively, INSTALLED_APPS
may contain the dotted path to a
configuration class to specify it explicitly:
INSTALLED_APPS = [
...
'polls.apps.PollsAppConfig',
...
]
Para autores de aplicações¶
Se você está criando uma app plugável chamada “Rock ‘n’ roll”, aqui está como você poderia prover um nome apropriado para o admin:
# rock_n_roll/apps.py
from django.apps import AppConfig
class RockNRollConfig(AppConfig):
name = 'rock_n_roll'
verbose_name = "Rock ’n’ roll"
RockNRollConfig
will be loaded automatically when INSTALLED_APPS
contains 'rock_n_roll'
. If you need to prevent this, set
default
to False
in the class definition.
You can provide several AppConfig
subclasses with different behaviors.
To tell Django which one to use by default, set default
to
True
in its definition. If your users want to pick a non-default
configuration, they must replace 'rock_n_roll'
with the dotted path to that
specific class in their INSTALLED_APPS
setting.
The AppConfig.name
attribute tells Django which application this
configuration applies to. You can define any other attribute documented in the
AppConfig
API reference.
AppConfig
subclasses may be defined anywhere. The apps.py
convention merely allows Django to load them automatically when
INSTALLED_APPS
contains the path to an application module rather
than the path to a configuration class.
Nota
Se o seu código importa o registro de aplicações no __init__.py
da aplicação, o nome apps
irá conflitar com o sub-módulo apps
. A melhor prática é mover esse código para um sub-módulo e importá-lo. Uma alternativa é importar o registro com um nome diferente:
from django.apps import apps as django_apps
In previous versions, a default_app_config
variable in the application
module was used to identify the default application configuration class.
Para usuários de aplicações¶
Se você está usando “Rock ’n’ roll” em um projeto chamado anthology
, mas quer mostrá-lo como “Jazz Manouche”, você pode fornecer sua própria configuração:
# 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',
# ...
]
This example shows project-specific configuration classes located in a
submodule called apps.py
. This is a convention, not a requirement.
AppConfig
subclasses may be defined anywhere.
In this situation, INSTALLED_APPS
must contain the dotted path to
the configuration class because it lives outside of an application and thus
cannot be automatically detected.
Configuração da aplicação¶
-
class
AppConfig
¶ Objetos de configuração de uma aplicação armazenam meta-dados para uma aplicacão. Alguns atributos podem ser configurados nas subclasses
AppConfig
. Outros são definidos pelo Django e são somente para leitura.
Atributos configuráveis¶
-
AppConfig.
name
¶ O caminho completo para do Python para a aplicação, exemplo:
'django.contrib.admin'
.Este atributo define a qual aplicação a configuração se aplica. deve ser definido em todas as subclasses de
AppConfig
.Ele deve ser único dentro de todo o projeto Django.
-
AppConfig.
label
¶ Nome curto para a aplicação, ex.
'admin'
Este atributo permite trocar o rótulo de uma aplicação quando duas aplicações tem rótulos conflitantes. Seu valor padrão é um último componente de
name
. ELe deve ser uma identificador Python válido.Ele deve ser único dentro de todo o projeto Django.
-
AppConfig.
verbose_name
¶ Nome legível para a aplicação, ex. “Administração”.
O atributo padrão para `` label.title()``.
-
AppConfig.
path
¶ caminho no Sistema de arquivo para o diretório da aplicação , ex.: ‘/usr/lib/pythonX.Y/dist-packages/django/contrib/admin’`.
Na maioria dos casos, o Django pode automaticamente detectar e definir isso, mas você pode explicitamente sobrepor como um atributo de classe na sua sublcasse de
AppConfig
. Em alguma situações isso é requerido; por exemplo se o pacote da aplicação é um namespace package com míltiplos caminhos.
-
AppConfig.
default
¶ - New in Django 3.2.
Set this attribute to
False
to prevent Django from selecting a configuration class automatically. This is useful whenapps.py
defines only oneAppConfig
subclass but you don’t want Django to use it by default.Set this attribute to
True
to tell Django to select a configuration class automatically. This is useful whenapps.py
defines more than oneAppConfig
subclass and you want Django to use one of them by default.Por padrão, este atributo não é definido.
-
AppConfig.
default_auto_field
¶ - New in Django 3.2.
The implicit primary key type to add to models within this app. You can use this to keep
AutoField
as the primary key type for third party applications.Por padrão, este é o valor de
DEFAULT_AUTO_FIELD
.
Atributos somente leitura¶
-
AppConfig.
module
¶ Root module for the application, e.g.
<module 'django.contrib.admin' from 'django/contrib/admin/__init__.py'>
.
-
AppConfig.
models_module
¶ Módulo contendo os models, e.g.
<module 'django.contrib.admin.models' from 'django/contrib/admin/models.py'>
.Isso pode ser
None
se a aplicação nao contém um módulomodels
. Note que os sinais relacionados com o banco de dados tal comopre_migrate
epost_migrate
somente são emitidos por aplicações que conténham o módulomodels
.
Métodos¶
-
AppConfig.
get_models
()¶ Retornar um iterável de classes
Model
para esta aplicação.Requer que o registro do aplicativo esteja totalmente povoado.
-
AppConfig.
get_model
(model_name, require_ready=True)¶ Retorna a
Model
com o nome dadomodel_name
.model_name
é insensível à capitularização -case-insensitive-.Resultará em :exc:’LookupError’ se esse modelo não existir na aplicação.
Requer o registro da aplicação para ser populado totalmente, a não ser que o argumento
require_ready
esteja definido comoFalse
.require_ready
se comporta exatamente como emapps.get_model()
.
-
AppConfig.
ready
()¶ Subclasses podem substituir este método para realizar tarefas de inicialização tal como registrar “signals”. Ele é chamado tão logo o registro seja populado.
Entretanto você não pode importar modelos a nível de modulo onde as classes
AppConfig
são definidas, você pode faze-lo inready()`, usando tanto uma instrução de ``import
ouget_model()
.Se estiver registrando
model signals
, você pode referenciar o emissor por um rotulo string ao invés da classe do modeloExemplo
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')
Aviso
Embora você possa acessar classes de modelo como descrito acima, evite interagir co o banco de dados dentro da implementação do seu
ready()
. Isso inclui métodos de modelos que executam “queries” (save()
,delete()
, métodos de gerenciamento e etc.), e também “queries” SQL explicitas através dodjango.db.connection
. Seu métodoready()
irá rodar durante o início de cada comando de gerenciamento. Por exemplo, apesar de a configuração do banco de dados de teste ser separado das definições de produção, omanage.py test
ainda poderia executar algumas “queries” no seu banco de dados de produção.Nota
No processo de inicialização normal, o método
ready
somente é chamado uma vez pelo Django. Mas em alguns casos excepcionais, particularmente em testes os quais estão mexendo com aplicações instaladas, oready
talvez seja chamado mais de uma vez. Neste caso, ou escreva métodos indepotentes, ou coloque um indicador nas suas classesAppConfig
para prevenir re-executar código o qual deveria rodar exatamente uma vez.
Namespace packages as apps¶
Pacotes Python sem o “__init__.py” são conhecidos como “namespace packages” e podem estar espalhados entre multiplos diretorios em locais diferentes em “sys.path” (veja :pep:’420’).
Aplicações Django requerem um único caminho baseado no sistema de arquivos onde o Django (dependendo da configuração) irá procurar por templates, ativos estáticos, etc. Sendo assim, pacotes de espaço de nomes podem ser aplicações Django somente se uma das seguintes for verdadeiro:
- O pacote de espaço de nome tem na verdade somente um localização (ex.: não está distribuído em mais de um diretório)
- A classe
AppConfig
usada para configurar a aplicação tem um atributo de classepath
, o qual é o caminho absoluto do diretório que o Django irá usar como o único caminho básico para a aplicação.
Se nenhuma destas condições forem atendidas, Django irá emitir um erro ImproperlyConfigured
.
Registro do Aplicativo¶
-
apps
¶ O registro da aplicação fornece a seguinte API pública. Métodos que não estão listados abaixo são considerados privados e talvez mudem sem serem noticiados.
-
apps.
ready
¶ Atributo booleano que é passado para
True
depois que o registro está totalmente populado e todos os métodosAppConfig.ready()
são chamados.
-
apps.
get_app_config
(app_label)¶ Retorna uma
AppConfig
para a aplicação com o dadoapp_label
. Emite um erroLookupError
se tal aplicação não existir.
-
apps.
is_installed
(app_name)¶ Verifique se uma aplicação com o dado nome existe no registro.
app_name
é o nome completo da app, exemplo'django.contrib.admin'
.
-
apps.
get_model
(app_label, model_name, require_ready=True)¶ Retorna a
Model
com o dadoapp_label
e``model_name``. Como um atalho, esse método também aceita um simples argumento na forma deapp_label.model_name
.model_name
é case-insensitive, ou seja, não diferencia maiúsculas e minúsculas.Emite
LookupError
se a tal aplicação ou modelo não existir. EmiteValueError
quando chamado com um argumento único que não contém exatamente um ponto.Requer o registro da aplicação para ser populado totalmente, a não ser que o argumento
require_ready
esteja definido comoFalse
.Definindo o
require_ready
paraFalse
permite procurar por padrões :ref:` enquanto o registro da aplicação esta sendo preenchido <app-loading-process>`, especificamente durante a segunda fase onde ele importa os modelos/padroes. Entãoget_model()
têm o mesmo efeito de importar um modelo. O caso de uso principal é para configurar as classes de modelo com configurações, comoAUTH_USER_MODEL
.Quando
require_ready
éFalse
,get_model()
retorna uma classe de modelo que talvez não seja totalmente funcional (acessores reversos podem estar faltando, por exemplo) enquanto o registro do app não está completo. Por isso, é melhor deixarrequire_ready
com seu valor padrãoTrue
sempre que possível.
Processo de Inicialização¶
Como as aplicações são carregadss¶
Quando o Django inicia, a django.setup()
é responsável por popular o registro da aplicação.
-
setup
(set_prefix=True)[código fonte]¶ Configura o Django através:
- Carregando configurações
- Configurando o “logging”.
- Se
set_prefix
é igual a True, definindo o prefixo do escript que resolve URL paraFORCE_SCRIPT_NAME
se estiver definido, ou caso contrário para/
. - Inicializando o registro do aplicativo.
Essa função é chamada automáticamente.
- Quando rodar um servidor HTTP via suporte WSGI do Django.
- Quando invocar um comando de gerenciamento.
Ele deve ser chamado explicitamente em outros casos, por exemplo em scripts Python.
O registro da aplicaçào é inicializado em três estágios. Em cada estágio, o Django processa todas as aplicações na ordem que estÃo em INSTALLED_APPS
.
Primeiro Django importa cada item que está no
INSTALLED_APPS
.If it’s an application configuration class, Django imports the root package of the application, defined by its
name
attribute. If it’s a Python package, Django looks for an application configuration in anapps.py
submodule, or else creates a default application configuration.Neste momento, seu código não deveria importar nenhum modelo!
Em outras opalavras, os pacotes da raiz da sua aplicação e os módulos que definem sua classes de configuração da aplicação não deveriam importar nenhum modelo, mesmo que indiretamente.
Falando estritamente, o Django permite importar modelos uma vez que a aplicação de configuração está carregada. No entanto , a fim de evitar limitações desnecessárias na ordem definida em
INSTALLED_APPS
, recomendamos fortemente não importar qualquer modelo neste estágio.Uma vez que este estágio se complete, as APIs que manipulam as configurações da aplicação tal como
get_app_config()
se tornam disponíveis.Então o Django tenta importar o submódulo
models
de cada aplicação, se houver uma.Você deve definir ou importar todos os modelos no seu
models.py
ou nomodels/__init__.py
da sua aplicação. De outtro modo, o registro da aplicação talvez não seja totalmente populado neste ponto, o que pode causar um malfuncionamento do ORM.Uma vez que este estágio esteja completo, as APIs que operam nos modelos tal como
get_model()
se tornam usáveis.Finalmente o Django executa o método
ready()
de cada configuração da aplicação.
Solução de Problemas¶
Aqui estão alguns problemas comuns que você talvez encontre durante a inicialização:
AppRegistryNotReady
: Isso acontece quando se importa uma configuração de aplicação ou um módulo de um modelo que aciona um código que depende do registro do app.For example,
gettext()
uses the app registry to look up translation catalogs in applications. To translate at import time, you needgettext_lazy()
instead. (Usinggettext()
would be a bug, because the translation would happen at import time, rather than at each request depending on the active language.)Executar as queries de banco de dados com o ORM em tempo de importação nos módulo de modelos também irá disparar a mesma exceção. O ORM não pode funcionar devidamente até que todos os modelos estejam disponíveis.
Essa exceção também acontece se você chamar
django.setup()
em um script Python autônomo.ImportError: cannot import name ...
Isso acontece se a sequência de importação termina em um loop.Para eliminar tais problemas, você deve minimizar a dependências entre seus módulos de modelos e fazer o menos possível durante o tempo de importação. Para evitar a execução de código em tempo de imporatação você pode move-lo para uma função e cachear seus resultados. O código será executado quando você precisar dos resultados pela primeira vez. Este conceito é conhecido como “avaliação preguiçosa”.
django.contrib.admin
automaticamene realiza a auto-descoberta od módulos doadmin
nas aplicações instaladas. Para impedir isso, altere seuINSTALLED_APPS
para que contenha o'django.contrib.admin.apps.SimpleAdminConfig'
ao invés do'django.contrib.admin'
.