Spec-Zone.ru › Django 1.9

Приложения

Django содержит реестр установленных приложений, который хранит конфигурацию и предоставляет возможность интроспекции. Он также поддерживает список доступных моделей.

Этот реестр просто называется apps и доступен в django.apps:

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

Проекты и приложения

Термин проект описывает веб-приложение Django. Пакет проекта Python определяется в первую очередь модулем настроек, но обычно содержит и другие вещи. Например, при запуске django-admin startproject mysite вы получите каталог проекта mysite, который содержит пакет Python mysite с settings.py, urls.py, и wsgi.py. Пакет проекта часто расширяется, чтобы включать такие вещи, как фикстуры, CSS и шаблоны, которые не привязаны к конкретному приложению.

Корневой каталог проекта (тот, который содержит manage.py) обычно является контейнером для всех приложений проекта, которые не установлены отдельно.

Термин приложение описывает пакет Python, который предоставляет набор функций. Приложения могут быть повторно использованы в различных проектах.

Приложения включают в себя некоторое сочетание моделей, представлений, шаблонов, тегов шаблонов, статических файлов, URL-адресов, middleware и т. д. Они обычно подключаются к проектам с помощью настройки INSTALLED_APPS и необязательно с другими механизмами, такими как URLconf, настройкой MIDDLEWARE_CLASSES или наследованием шаблонов.

Важно понимать, что приложение 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'

Это заставит Django использовать 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, но хотите, чтобы он отображался как «Джаз Мануш», вы можете предоставить собственную конфигурацию:

# 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 — это соглашение, а не требование.

Конфигурация приложений

class AppConfig [source]

Объекты конфигурации приложений хранят метаданные для приложения. Некоторые атрибуты могут быть настроены в подклассах AppConfig. Другие устанавливаются Django и являются только для чтения.

Настраиваемые атрибуты

AppConfig.name

Полное имя модуля приложения, например, 'django.contrib.admin'.

Этот атрибут определяет, к какому приложению относится данная конфигурация. Он должен быть установлен во всех подклассах AppConfig.

Он должен быть уникальным в проекте Django.

AppConfig.label

Короткое имя приложения, например, 'admin'

Этот атрибут позволяет переименовать приложение, когда у двух приложений конфликтующие имена. По умолчанию он равен последнему элементу в name. Он должен быть допустимым идентификатором Python.

Он должен быть уникальным в проекте Django.

AppConfig.verbose_name

Человекопонятное имя приложения, например, «Администрирование».

Этот атрибут по умолчанию равен label.title().

AppConfig.path

Путь к каталогу приложения в файловой системе, например, '/usr/lib/python3.4/dist-packages/django/contrib/admin'.

В большинстве случаев Django может автоматически определить и установить его, но вы также можете предоставить явную замену в качестве атрибута класса вашего подкласса AppConfig. В некоторых ситуациях это необходимо; например, если пакет приложения — пространство имён с несколькими путями.

Атрибуты только для чтения

AppConfig.module

Основной модуль приложения, например, <module 'django.contrib.admin' from 'django/contrib/admin/__init__.pyc'>.

AppConfig.models_module

Модуль, содержащий модели, например, <module 'django.contrib.admin.models' from 'django/contrib/admin/models.pyc'>.

Он может быть None если приложение не содержит модуль models. Обратите внимание, что сигналы, связанные с базой данных, такие как pre_migrate и post_migrate, излучаются только для приложений, имеющих модуль models.

Методы

AppConfig.get_models() [source]

Возвращает итерируемый список классов Model для этого приложения.

AppConfig.get_model(model_name) [source]

Возвращает Model с заданным model_name. Вызывает LookupError, если такой модели нет в данном приложении. model_name регистронезависимо.

AppConfig.ready() [source]

Подклассы могут переопределить этот метод для выполнения задач инициализации, таких как регистрация сигналов. Вызывается сразу после того, как реестр полностью заполнен.

Вы не можете импортировать модели в модулях, определяющих классы конфигурации приложения, но вы можете использовать get_model(), чтобы получить класс модели по имени, например так:

def ready(self):
    MyModel = self.get_model('MyModel')

Предупреждение

Хотя вы можете получить доступ к классам моделей, как описано выше, избегайте взаимодействия с базой данных в реализации вашего метода ready(). Это включает методы моделей, которые выполняют запросы (save(), delete(), методы менеджера и т. д.), а также запросы к SQL напрямую через django.db.connection. Ваш метод ready() будет выполняться во время запуска каждой команды управления. Например, даже если конфигурация тестовой базы данных отличается от производственных настроек, manage.py test всё равно выполнит некоторые запросы к вашей **производственной** базе данных!

Примечание

В обычном процессе инициализации метод ready вызывается Django только один раз. Но в некоторых особых случаях, особенно в тестах, которые играются с установленными приложениями, ready может быть вызван более одного раза. В этом случае либо напишите идемпотентные методы, либо установите флаг в ваших классах AppConfig для предотвращения повторного запуска кода, который должен выполняться ровно один раз.

Пакеты имён как приложения (Python 3.3+)

Версии Python 3.3 и выше поддерживают пакеты Python без файла __init__.py. Эти пакеты известны как «пакеты имён» и могут быть распределены по нескольким каталогам в разных местах на sys.path (см. PEP 420).

Приложения Django требуют единственного базового пути к файловой системе, где Django (в зависимости от конфигурации) будет искать шаблоны, статические ресурсы и т. д. Таким образом, пакеты имён могут быть приложениями Django только в том случае, если выполняется одно из следующих условий:

  1. Пакет имён фактически имеет только одно местоположение (т. е. не распределен по более чем одному каталогу).
  2. Класс AppConfig, используемый для настройки приложения, имеет атрибут класса path, который представляет собой абсолютный путь к каталогу, который Django будет использовать в качестве единственного базового пути для приложения.

Если ни одно из этих условий не выполняется, Django вызовет ImproperlyConfigured.

Регистр приложений

apps

Регистр приложений предоставляет следующий публичный API. Методы, которые не указаны ниже, считаются закрытыми и могут быть изменены без предварительного уведомления.

apps.ready

Булевый атрибут, который устанавливается в True после того, как реестр полностью заполнен и все методы AppConfig.ready() вызваны.

apps.get_app_configs()

Возвращает итерируемый список экземпляров AppConfig.

apps.get_app_config(app_label)

Возвращает AppConfig для приложения с заданным app_label. Вызывает LookupError, если такое приложение не существует.

apps.is_installed(app_name)

Проверяет, существует ли приложение с заданным именем в реестре. app_name - полное имя приложения, например 'django.contrib.admin'.

apps.get_model(app_label, model_name)

Возвращает Model с заданным app_label и model_name. В качестве сокращения, этот метод также принимает один аргумент в формате app_label.model_name. model_name регистронезависимо.

Вызывает LookupError, если такое приложение или модель не существует. Вызывает ValueError, когда вызывается с одним аргументом, который не содержит ровно одну точку.

Процесс инициализации

Как загружаются приложения

При запуске Django за загрузку реестра приложений отвечает django.setup().

setup() [source]

Настраивает Django следующим образом:

  • Загрузка настроек.
  • Настройка ведения журнала.
  • Инициализация реестра приложений.

Эта функция вызывается автоматически:

  • При запуске HTTP-сервера через поддержку WSGI Django.
  • При вызове команды управления.

В других случаях она должна вызываться явно, например, в простых скриптах Python.

Регистр приложений инициализируется в три этапа. На каждом этапе Django обрабатывает все приложения в порядке INSTALLED_APPS.

  1. Сначала Django импортирует каждый элемент из INSTALLED_APPS.

    Если это класс конфигурации приложения, Django импортирует корневой пакет приложения, определённый его атрибутом name. Если это пакет Python, Django создаёт стандартную конфигурацию приложения.

    На этом этапе ваш код не должен импортировать модели!

    Другими словами, корневые пакеты ваших приложений и модули, которые определяют классы конфигурации вашего приложения, не должны импортировать модели, даже косвенно.

    Строго говоря, Django разрешает импортировать модели после того, как их конфигурация приложения загружена. Однако, чтобы избежать ненужных ограничений на порядок INSTALLED_APPS, настоятельно рекомендуется не импортировать модели на этом этапе.

    После завершения этого этапа API, которые работают с конфигурациями приложений, такие как get_app_config(), становятся доступны.

  2. Затем Django пытается импортировать подмодуль models каждого приложения, если он есть.

    Все модели должны быть определены или импортированы в подмодуле models.py или models/__init__.py вашего приложения. В противном случае регистр приложений может не быть полностью заполнен на этом этапе, что может привести к некорректной работе ORM.

    После завершения этого этапа API, которые работают с моделями, такие как get_model(), становятся доступны.

  3. Наконец, Django выполняет метод ready() каждой конфигурации приложения.

Отладка приложений

Вот некоторые распространённые проблемы, с которыми вы можете столкнуться во время инициализации:

  • AppRegistryNotReady Это происходит при импорте конфигурации приложения или модуля моделей, что вызывает код, зависящий от реестра приложений.

    Например, ugettext() использует реестр приложений для поиска каталогов переводов в приложениях. Чтобы выполнить перевод во время импорта, вам нужен ugettext_lazy() вместо него. (Использование ugettext() будет ошибкой, так как перевод произойдёт во время импорта, а не при каждом запросе в зависимости от активного языка.)

    Выполнение запросов к базе данных с ORM во время импорта в модулях моделей также вызовет эту ошибку. ORM не может работать должным образом, пока все модели не будут доступны.

    Ещё одним распространённым виновником является django.contrib.auth.get_user_model(). Используйте настройку AUTH_USER_MODEL для ссылки на модель пользователя во время импорта.

    Эта ошибка также возникает, если вы забыли вызвать django.setup() в автономном скрипте Python.

  • ImportError: cannot import name ... Это происходит, если последовательность импорта зацикливается.

    Чтобы устранить такие проблемы, вы должны свести к минимуму зависимости между вашими модулями моделей и выполнить как можно меньше работы во время импорта. Чтобы избежать выполнения кода во время импорта, вы можете перенести его в функцию и кэшировать её результаты. Код будет выполнен, когда вы впервые получите результаты. Эта концепция известна как «ленивая оценка».

  • django.contrib.admin автоматически выполняет автоматическое обнаружение admin модулей в установленных приложениях. Чтобы этого избежать, измените свой INSTALLED_APPS так, чтобы он содержал 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin'.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.9/ref/applications/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API