Приложения ¶
Django содержит реестр установленных приложений, в котором хранится конфигурация и обеспечивается самоанализ. Он также поддерживает список доступных моделей .
Этот регистр называется apps
и доступен в django.apps
:
>>> from django.apps import apps
>>> apps.get_app_config('admin').verbose_name
'Administration'
Проекты и приложения ¶
Термин проект описывает веб-приложение Django. Пакет Python проекта определяется в первую очередь модулем настроек settings
, но обычно он содержит другие вещи. Например, при запуске , вы получите каталог проекта , содержащий пакет Python с файлами , , и . Пакет проекта часто расширяется за счет добавления таких вещей, как снимки, файлы CSS и шаблоны, не связанные с конкретным приложением.django-admin startproject monsite
monsite
monsite
settings.py
urls.py
asgi.py
wsgi.py
Корневой каталог проекта (тот , который содержит manage.py
), как правило, контейнер для всех приложений в проекте, которые не установлены отдельно.
Термин « приложение» описывает пакет Python, который предоставляет определенный набор функций. Приложения можно повторно использовать в разных проектах.
Приложения включают в себя комбинацию моделей, представлений, шаблонов, тегов шаблонов, статических файлов, URL-адресов, промежуточного ПО и т. Д. Обычно они связаны с проектами через настройку INSTALLED_APPS
и, возможно, с другими механизмами, такими как конфигурации URL, настройка MIDDLEWARE
или наследование шаблонов.
Важно понимать, что приложение Django - это набор кода, который взаимодействует с различными частями системы. Нет объекта Application
как такового. Однако есть несколько мест, где Django необходимо взаимодействовать с установленными приложениями, в основном для настройки, а также для самоанализа. Таким образом, реестр приложений поддерживает метаданные в экземпляре AppConfig
для каждого установленного приложения.
Нет ограничений на то, что пакет проекта не может также считаться приложением и что он содержит шаблоны и т. Д. (что потребует добавления его в список INSTALLED_APPS
).
Настройка приложений ¶
Чтобы настроить приложение, унаследуйте AppConfig
и поместите путь к этому подклассу с синтаксисом, указанным в INSTALLED_APPS
.
Если INSTALLED_APPS
содержит путь к модулю приложения с синтаксисом, разделенным точками, Django ищет переменную default_app_config
в этом модуле.
Если установлено, это путь синтаксиса, указывающий на подкласс AppConfig
этого приложения.
Если нет default_app_config
, Django использует базовый класс AppConfig
.
default_app_config
Позволяет приложениям, созданным до Django 1.7, например django.contrib.admin
переходить к функциональным возможностям, AppConfig
не требуя от пользователей обновления их настроек INSTALLED_APPS
.
Новых приложений следует избегать default_app_config
. Скорее, они должны требовать, чтобы путь к AppConfig
соответствующему подклассу был явно указан в настройке INSTALLED_APPS
.
Авторам приложений ¶
Если вы создаете многоразовое приложение под названием «Рок-н-ролл», вот как вы можете определить подходящее имя для интерфейса администратора:
# rock_n_roll/apps.py
from django.apps import AppConfig
class RockNRollConfig(AppConfig):
name = 'rock_n_roll'
verbose_name = "Rock ’n’ roll"
Вы можете заставить свое приложение загружать этот подкласс AppConfig
по умолчанию следующим образом:
# rock_n_roll/__init__.py
default_app_config = 'rock_n_roll.apps.RockNRollConfig'
Это приводит к использованию только RockNRollConfig
когда INSTALLED_APPS
содержит 'rock_n_roll'
. Это позволяет использовать функции, AppConfig
не требуя от пользователей обновления своих настроек INSTALLED_APPS
. Вне этого варианта использования лучше избегать использования, default_app_config
а вместо этого указать класс конфигурации приложения, INSTALLED_APPS
как описано ниже.
Вы также можете попросить своих пользователей ввести 'rock_n_roll.apps.RockNRollConfig'
свои INSTALLED_APPS
настройки. Вы даже можете предоставить несколько разных
AppConfig
подклассов с разным поведением и позволить пользователям выбирать один из них через свои INSTALLED_APPS
настройки.
Рекомендуемое соглашение - поместить класс конфигурации в именованный подмодуль приложения apps
. Однако Django этого не требует.
Вы должны включить атрибут, name
чтобы Django мог определить, к какому приложению применяется эта конфигурация. Вы можете установить любой атрибут, описанный в справочнике по API AppConfig
.
Заметка
Если ваш код импортирует реестр __init__.py
приложения в файл приложения, имя apps
будет конфликтовать с подмодулем apps
. Лучший подход - переместить этот код в подмодуль и импортировать его. Обходной путь - импортировать реестр с другим именем:
from django.apps import apps as django_apps
Для пользователей приложения ¶
Если вы используете рок-н-ролл в вызванном проекте anthology
, но вместо этого хотите, чтобы он отображался как «Jazz Manouche», вы можете указать свою собственную конфигурацию:
# 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',
# ...
]
Опять же, определение классов конфигурации для конкретного проекта в вызываемом подмодуле apps
- это соглашение, а не требование.
Настройка приложений ¶
-
класс
AppConfig
[источник] ¶ Объекты конфигурации приложения хранят метаданные для приложения. Некоторые атрибуты можно настроить в подклассах
AppConfig
. Остальные определены Django и доступны только для чтения.
Настраиваемые атрибуты ¶
-
AppConfig.
name
¶ Полный путь Python к приложению, например
'django.contrib.admin'
,Этот атрибут определяет, к какому приложению применяется конфигурация. Он должен быть определен во всех подклассах
AppConfig
.Он должен быть уникальным в контексте того же проекта Django.
-
AppConfig.
label
¶ Краткое название приложения, например.
'admin'
Этот атрибут используется для изменения метки приложения, когда два приложения имеют несовместимые метки. По умолчанию
label
это последний элементname
. Это должен быть действующий идентификатор Python.Он должен быть уникальным в контексте того же проекта Django.
-
AppConfig.
verbose_name
¶ Понятное имя приложения, например. «Администрация».
По умолчанию этот атрибут эквивалентен
label.title()
.
-
AppConfig.
path
¶ Путь файловой системы к каталогу приложения, например.
'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'
,В большинстве случаев Django может автоматически обнаруживать и устанавливать этот атрибут, но вы также можете предоставить явное переопределение в качестве атрибута класса для подкласса
AppConfig
. В некоторых случаях это необходимость; например, если пакет приложения представляет собой пакет пространства имен с несколькими путями.
Атрибуты только для чтения ¶
-
AppConfig.
module
¶ Корневой модуль приложения, например. ,
<module 'django.contrib.admin' from 'django/contrib/admin/__init__.py'>
-
AppConfig.
models_module
¶ Модуль, содержащий модели, например. ,
<module 'django.contrib.admin.models' from 'django/contrib/admin/models.py'>
Может быть действительным,
None
если приложение не содержит модуляmodels
. Обратите внимание, что сигналы, относящиеся к базе данных, такие какpre_migrate
иpost_migrate
, испускаются только для приложений, у которых есть модульmodels
.
Методы ¶
-
AppConfig.
get_models
() [источник] ¶ Возвращает повторяемый объект классов
Model
для этого приложения.Требуется полное определение реестра приложений.
-
AppConfig.
get_model
( Model_name , require_ready = True ) [источник] ¶ Возвращает класс
Model
сmodel_name
заданным именем .model_name
нечувствителен к регистру.Генерируется,
LookupError
если в этом приложении не существует шаблона с таким именем.Требуется реестра приложений , чтобы быть полностью установлен, кроме случаев , когда параметр
require_ready
являетсяFalse
.require_ready
ведет себя так же, как и дляapps.get_model()
.
-
AppConfig.
ready
() [источник] ¶ Подклассы могут расширять этот метод для выполнения задач инициализации, таких как регистрация сигналов. Он вызывается, как только реестр будет полностью заполнен.
Хотя невозможно импортировать модели на уровне модуля, в котором
AppConfig
определены классы , их можно импортировать сready()
помощью оператораimport
илиget_model()
.Если вы зарегистрируетесь , вы можете ссылаться на отправителя по его текстовой метке вместо использования самого класса шаблона.
signaux de modèle
Пример:
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')
Предупреждение
Хотя вы можете получить доступ к классам модели, как описано выше, избегайте взаимодействия с базой данных при реализации
ready()
. Это включает в себя методы , которые выполняют запросы модели (save()
,delete()
методы менеджеров модели и т.д.), а также необработанных запросов SQL черезdjango.db.connection
. Методready()
выполняется при запуске каждой команды управления. Например, несмотря на то, что конфигурация тестовой базы данных отделена от производственных параметров, все же можно выполнять запросы к вашей производственной базе данных !manage.py test
Заметка
В обычном процессе инициализации метод
ready
вызывается Django только один раз. Но в некоторых пограничных случаях, особенно в тестах, управляющих установленными приложениями,ready
может вызываться более одного раза. В этом случае либо напишите идемпотентные методы, либо установите флаг в своих классах,AppConfig
чтобы предотвратить повторное выполнение кода, который должен выполняться только один раз.
Пакеты с пространством имен как приложения ¶
Пакеты Python без файла называются «пакетами пространства имен» и могут быть разбросаны по нескольким каталогам и в разных местах (см.__init __.py
sys.path
PEP 420 ).
Приложениям Django требуется уникальный базовый путь к файловой системе, по которому Django (в зависимости от конфигурации) ищет шаблоны, статические файлы и т. Д. Таким образом, пакеты пространства имен могут быть приложениями Django только при выполнении одного из следующих условий:
- Пакет пространства имен на самом деле имеет только одно местоположение (то есть он не разбросан более чем по одному каталогу).
- Класс,
AppConfig
используемый для настройки приложения, имеет атрибут классаpath
, соответствующий абсолютному пути к каталогу, который Django использует в качестве уникального базового пути для приложения.
Если ни одно из этих условий не выполняется, Django выдает исключение ImproperlyConfigured
.
Реестр приложений ¶
-
apps
¶ Реестр приложений предоставляет следующий общедоступный API. Методы, не перечисленные ниже, считаются частными и могут быть изменены без предварительного уведомления.
-
apps.
ready
¶ Логический атрибут устанавливается в значение
True
после полного заполнения реестра и вызова всех методовAppConfig.ready()
.
-
apps.
get_app_config
( app_label ) ¶ Возвращает экземпляр
AppConfig
приложения, соответствующегоapp_label
. Генерируется,LookupError
если такое приложение не существует.
-
apps.
is_installed
( имя_приложения ) ¶ Проверяет, существует ли в реестре приложение с указанным именем.
app_name
- полное название приложения, например.'django.contrib.admin'
,
-
apps.
get_model
( app_label , model_name , require_ready = True ) ¶ Возвращает класс ,
Model
соответствующий кapp_label
и параметрамmodel_name
. Этот метод также принимает в качестве ярлыка один параметр формыapp_label.model_name
.model_name
нечувствителен к регистру.Генерируется,
LookupError
если подходящего приложения или шаблона не существует. Генерируется,ValueError
когда предоставляется единственный параметр, не содержащий ровно одной точки.Требуется реестра приложений , чтобы быть полностью установлен, кроме случаев , когда параметр
require_ready
являетсяFalse
.Установка
require_ready
дляFalse
позволяет просматривать модели в то время как реестр приложений заселяются , особенно во второй фазе , где модели импортируются.get_model()
поэтому имеет тот же эффект, что и импорт модели. Основным вариантом использования является настройка классов модели на основе таких параметров, какAUTH_USER_MODEL
.Когда
require_ready
это равноFalse
,get_model()
возвращает класс модели , которая не может быть полностью функциональной (например, доступ к обратным отношениям может отсутствовать) время ожидания в реестр приложения будет полностью заселен. По этой причине лучше по возможности оставить значениеrequire_ready
по умолчаниюTrue
.
Процесс инициализации ¶
Загрузка приложений ¶
При запуске Django django.setup()
отвечает за заполнение реестра приложения.
-
setup
( set_prefix = True ) [источник] ¶ Настраивает Django в:
- настройки загрузки;
- настройка логирования;
- Если
set_prefix
естьTrue
, установив префикс сценария разрешения URL дляFORCE_SCRIPT_NAME
если он установлен , или иначе/
. - инициализация реестра приложений.
Эта функция вызывается автоматически:
- при запуске HTTP-сервера через поддержку WSGI Django;
- при вызове команды управления.
Его следует вызывать явно в других случаях, например, в обычных скриптах Python.
Реестр приложений инициализируется в три этапа. На каждом этапе Django обрабатывает все приложения в порядке INSTALLED_APPS
.
Во-первых, Django импортирует все элементы из файлов
INSTALLED_APPS
.Если это класс конфигурации приложения, Django импортирует корневой пакет приложения, определенный его атрибутом
name
. Если это пакет Python, Django создает конфигурацию приложения по умолчанию.На этом этапе ваш код не должен импортировать модели!
Другими словами, корневые пакеты ваших приложений и модули, определяющие классы конфигурации вашего приложения, не должны импортировать шаблоны, даже косвенно.
Строго говоря, Django позволяет импортировать модели после загрузки конфигурации их приложения. Однако, чтобы избежать ненужных ограничений для порядка в
INSTALLED_APPS
, настоятельно рекомендуется не импортировать модели на этом этапе.После завершения этого шага API-интерфейсы, которые используют конфигурации приложений, например,
get_app_config()
становятся пригодными для использования.Затем Django пытается импортировать подмодуль
models
каждого приложения, если он существует.Вам необходимо определить или импортировать все модели в файлы
models.py
илиmodels/__init__.py
ваше приложение. В противном случае реестр приложений может быть заполнен не полностью на этом этапе, что приведет к сбоям в работе ORM.После завершения этого шага API-интерфейсы, которые действуют на модели, например,
get_model()
становятся пригодными для использования.Наконец, Django выполняет метод
ready()
каждой конфигурации приложения.
Устранение неполадок ¶
Вот некоторые типичные проблемы, с которыми вы можете столкнуться во время инициализации:
AppRegistryNotReady
: Это происходит, когда при импорте конфигурации приложения или модуля шаблона выполняется код, зависящий от реестра приложения.Например,
gettext()
использует реестр приложений для поиска каталогов переводов в приложениях. Для перевода во время импорта вы должны использоватьgettext_lazy()
вместо этого (использованиеgettext()
будет ошибкой, потому что перевод будет выполняться во время импорта, а не при каждом запросе в зависимости от активного языка) ,Выполнение запросов к базе данных с ORM во время импорта в модули модели также вызывает это исключение. ORM не может работать должным образом, пока не будут доступны все модели.
Это исключение также возникает, если вы забыли вызвать
django.setup()
автономный скрипт Python.ImportError: cannot import name ...
Это происходит, если последовательность импорта представляет собой цикл.Чтобы устранить такие проблемы, вам следует уменьшить зависимости между модулями вашей модели и выполнять как можно меньше работы во время импорта. Чтобы избежать запуска кода во время импорта, вы можете переместить его в функцию и кэшировать ее результаты. Код будет выполнен в первый раз, когда вам понадобятся его результаты. Эта концепция известна как «отложенная оценка».
django.contrib.admin
автоматически выполняет обнаружение модулейadmin
в установленных приложениях. Чтобы предотвратить это, измените настройкуINSTALLED_APPS
на содержать'django.contrib.admin.apps.SimpleAdminConfig'
вместо'django.contrib.admin'
.