0

Где разместить код инициализации Django?

17

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

from django.core import management
management.call_command('syncdb', interactive=False)

Помещение этого кода в settings.py не сработало, так как для его выполнения требуется, чтобы настройки уже были загружены.

Попытка разместить код в представлении и доступ к этому представлению извне также не удалась, поскольку есть некоторые промежуточные слои (middlewares), которые используют базу данных, и они выдают ошибку, тем самым не позволяя мне получить доступ к представлению.

Поместить код в промежуточное программное обеспечение (middleware) было бы возможно, но такое решение сработало бы каждый раз при обращении к приложению. Одно из возможных решений - создать промежуточное программное обеспечение, которое выполнит всю работу и затем удалит себя из MIDDLEWARE_CLASSES, чтобы больше не вызываться. Могу ли я это сделать без значительных изменений в коде (monkey-patching)?

5 ответ(ов)

0

Если вы работаете с Django 1.7 и выше и хотите выполнить некоторый код при старте приложения, следуя при этом двум условиям:

1. Не выполнять его при миграциях (migrate), создании миграций (makemigrations), в интерактивной оболочке и т.д.

2. Избежать повторного выполнения кода

Решением будет использование следующего подхода:

Создайте файл myapp/apps.py с содержимым:

from django.apps import AppConfig

def startup():
    # Здесь размещается ваш код, который нужно выполнить при старте

class MyAppConfig(AppConfig):
    name = 'myapp'
    verbose_name = "Мое Приложение"

    def ready(self):
        import os
        if os.environ.get('RUN_MAIN'):
            startup()

Затем в файле myapp/__init__.py добавьте строку для регистрации вашего класса конфигурации приложения:

default_app_config = 'myapp.apps.MyAppConfig'

Данный подход использует рекомендации от @Pykler и @bdoering.

0

Если вы используете Apache/mod_wsgi, вам нужно воспользоваться WSGI скриптом, описанным по следующему адресу:

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

Добавьте необходимые вам строки после активации языковых переводов.

Таким образом, ваш код будет выглядеть следующим образом:

import sys

sys.path.insert(0, '/usr/local/django/mysite')

import settings

import django.core.management
django.core.management.setup_environ(settings)
utility = django.core.management.ManagementUtility()
command = utility.fetch_command('runserver')

command.validate()

import django.conf
import django.utils

django.utils.translation.activate(django.conf.settings.LANGUAGE_CODE)

# Ваша строка здесь.
django.core.management.call_command('syncdb', interactive=False)

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

Не забудьте заменить строку # Ваша строка здесь. на нужную вам команду или инициализацию, которая должна выполняться после активации переводов. Примечание: в современных версиях Django используйте migrate вместо syncdb, так как syncdb устарел.

0

Вы можете создать собственную команду и реализовать ваш код в функции handle. Подробности можно найти здесь: документация Django.

После этого вы можете создать скрипт запуска, который сначала запустит сервер Django, а затем выполнит вашу новую пользовательскую команду.

0

Если вы используете mod_wsgi, вы можете поместить это в стартовую функцию вашего WSGI-приложения.

0

Если вы сталкиваетесь с проблемой отсутствия сигнала запуска в Django, вот как я обошёл это ограничение:

Я создал специальное приложение, основываясь на идее Росса Макафарланда. Код, который вызывается в этом приложении, специфичен для моего проекта djangosite, но сам трюк может быть применён и в других проектах.

Вы можете ознакомиться с кодом по следующей ссылке: Django site models.py.

Надеюсь, это поможет вам решить вашу проблему!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь