Приложения ¶
Django содержит реестр установленных приложений, в котором хранится конфигурация и обеспечивается самоанализ. Он также поддерживает список доступных моделей .
Этот реестр называется apps
и доступен в
django.apps
:
>>> from django.apps import apps
>>> apps.get_app_config('admin').verbose_name
'Administration'
Проекты и приложения ¶
Термин проект описывает веб-приложение Django. Пакет Python проекта определяется в первую очередь модулем настроек, но обычно он содержит другие вещи. Например, при запуске
вы получите каталог проекта , который содержит пакет Python с , , и . Пакет проекта часто расширяется за счет включения таких вещей, как фикстуры, CSS и шаблоны, которые не привязаны к конкретному приложению.django-admin startproject mysite
mysite
mysite
settings.py
urls.py
asgi.py
wsgi.py
А корневой каталог проекта (тот , который содержит manage.py
), как правило , контейнер для всех применений проекта , которые не установлены отдельно.
Термин « приложение» описывает пакет Python, который предоставляет некоторый набор функций. Приложения могут быть повторно использованы в различных проектах.
Приложения включают в себя некоторую комбинацию моделей, представлений, шаблонов, тегов шаблонов, статических файлов, URL-адресов, промежуточного программного обеспечения и т. Д. Они обычно связаны с проектами с INSTALLED_APPS
настройкой и, необязательно, с другими механизмами, такими как URLconfs, MIDDLEWARE
настройка или наследование шаблонов.
Важно понимать, что приложение Django - это набор кода, который взаимодействует с различными частями фреймворка. Нет такой вещи, как Application
объект. Однако есть несколько мест, где Django необходимо взаимодействовать с установленными приложениями, в основном для настройки, а также для самоанализа. Вот почему реестр приложений поддерживает метаданные в
AppConfig
экземпляре для каждого установленного приложения.
Нет никаких ограничений, что пакет проекта не может также рассматриваться как приложение и иметь модели и т. Д. (Что потребовало бы его добавления
INSTALLED_APPS
).
Настройка приложений ¶
Чтобы настроить приложение, создайте apps.py
модуль внутри приложения, а затем определите его подкласс AppConfig
.
Когда INSTALLED_APPS
содержит пунктирный путь к модулю приложения, по умолчанию, если Django находит ровно один AppConfig
подкласс в apps.py
подмодуле, он использует эту конфигурацию для приложения. Это поведение можно отключить, установив AppConfig.default
значение False
.
Если apps.py
модуль содержит более одного AppConfig
подкласса, Django будет искать единственный, где AppConfig.default
находится True
.
Если AppConfig
подкласс не найден, AppConfig
будет использоваться базовый класс.
В качестве альтернативы INSTALLED_APPS
может содержать пунктирный путь к классу конфигурации, чтобы явно указать его:
INSTALLED_APPS = [
...
'polls.apps.PollsAppConfig',
...
]
Для авторов приложений ¶
Если вы создаете подключаемое приложение под названием «Рок-н-ролл», вы можете указать собственное имя для администратора следующим образом:
# rock_n_roll/apps.py
from django.apps import AppConfig
class RockNRollConfig(AppConfig):
name = 'rock_n_roll'
verbose_name = "Rock ’n’ roll"
RockNRollConfig
будет загружен автоматически, когда он INSTALLED_APPS
содержит 'rock_n_roll'
. Если вам нужно , чтобы предотвратить это, набор
default
для False
в определении класса.
Вы можете предоставить несколько AppConfig
подклассов с различным поведением. Чтобы указать Django, какой из них использовать по умолчанию, установите default
значение
True
в его определении. Если ваши пользователи хотят выбрать конфигурацию, отличную от конфигурации по умолчанию, они должны заменить 'rock_n_roll'
путь с точками к этому конкретному классу в своих INSTALLED_APPS
настройках.
AppConfig.name
Атрибут указывает , какое приложение Django эта конфигурация применяется к. Вы можете определить любой другой атрибут, задокументированный в AppConfig
справочнике по
API.
AppConfig
подклассы могут быть определены где угодно. apps.py
Конвенции просто позволяет Django загружать их автоматически , когда
INSTALLED_APPS
содержит путь к модулю приложения , а не на пути к классу конфигурации.
Примечание
Если ваш код импортирует реестр приложения в приложение
__init__.py
, имя apps
будет конфликтовать с apps
подмодулем. Лучше всего переместить этот код в подмодуль и импортировать его. Обходной путь - импортировать реестр под другим именем:
from django.apps import apps as django_apps
В предыдущих версиях default_app_config
переменная в модуле приложения использовалась для определения класса конфигурации приложения по умолчанию.
Для пользователей приложения ¶
Если вы используете «Рок-н-ролл» в названном проекте 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.py
. Это соглашение, а не требование.
AppConfig
подклассы могут быть определены где угодно.
В этой ситуации INSTALLED_APPS
должен содержать пунктирный путь к классу конфигурации, поскольку он находится вне приложения и, следовательно, не может быть обнаружен автоматически.
Конфигурация приложения ¶
-
класс
AppConfig
¶ Объекты конфигурации приложения хранят метаданные для приложения. Некоторые атрибуты можно настроить в
AppConfig
подклассах. Остальные устанавливаются Django и доступны только для чтения.
Настраиваемые атрибуты ¶
-
AppConfig.
name
¶ Полный путь Python к приложению, например
'django.contrib.admin'
.Этот атрибут определяет, к какому приложению применяется конфигурация. Он должен быть установлен во всех
AppConfig
подклассах.Он должен быть уникальным для проекта Django.
-
AppConfig.
label
¶ Краткое название приложения, например
'admin'
Этот атрибут позволяет перемаркировать приложение, когда два приложения имеют конфликтующие метки. По умолчанию используется последний компонент
name
. Это должен быть действительный идентификатор Python.Он должен быть уникальным для проекта Django.
-
AppConfig.
verbose_name
¶ Удобочитаемое имя приложения, например «Администрация».
По умолчанию этот атрибут имеет значение
label.title()
.
-
AppConfig.
path
¶ Путь файловой системы к каталогу приложения, например
'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'
.В большинстве случаев Django может автоматически определять и устанавливать это, но вы также можете предоставить явное переопределение в качестве атрибута класса для своего
AppConfig
подкласса. В некоторых ситуациях это требуется; например, если пакет приложения является пакетом пространства имен с несколькими путями.
-
AppConfig.
default
¶ - Новое в Django 3.2.
Установите для этого атрибута значение,
False
чтобы Django не выбирал класс конфигурации автоматически. Это полезно, когдаapps.py
определяется только одинAppConfig
подкласс, но вы не хотите, чтобы Django использовал его по умолчанию.Установите для этого атрибута значение,
True
чтобы сообщить Django о необходимости автоматического выбора класса конфигурации. Это полезно, когдаapps.py
определяется более одногоAppConfig
подкласса, и вы хотите, чтобы Django использовал один из них по умолчанию.По умолчанию этот атрибут не установлен.
-
AppConfig.
default_auto_field
¶ - Новое в Django 3.2.
Неявный тип первичного ключа, добавляемый к моделям в этом приложении. Вы можете использовать его в
AutoField
качестве типа первичного ключа для сторонних приложений.По умолчанию это значение
DEFAULT_AUTO_FIELD
.
Атрибуты только для чтения ¶
-
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
( имя_модели , require_ready = True ) ¶ Возвращает
Model
с заданнымmodel_name
.model_name
не учитывает регистр.Возникает,
LookupError
если в этом приложении нет такой модели.Требует, чтобы реестр приложения был полностью заполнен, если для
require_ready
аргумента не задано значениеFalse
.require_ready
ведет себя точно так же, как вapps.get_model()
.
-
AppConfig.
ready
() ¶ Подклассы могут переопределить этот метод для выполнения задач инициализации, таких как регистрация сигналов. Он вызывается, как только реестр будет полностью заполнен.
Хотя вы не можете импортировать модели на уровне модуля, где
AppConfig
определены классы, вы можете импортировать ихready()
с помощьюimport
оператора илиget_model()
.Если вы регистрируетесь , вы можете ссылаться на отправителя по его строковой метке вместо использования самого класса модели.
model signals
Пример:
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 ищет конфигурацию приложения вapps.py
подмодуле или создает конфигурацию приложения по умолчанию.На этом этапе ваш код не должен импортировать никаких моделей!
Другими словами, корневые пакеты ваших приложений и модули, которые определяют классы конфигурации вашего приложения, не должны импортировать какие-либо модели, даже косвенно.
Строго говоря, 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'
.