Где разместить код запуска Django?
Я хотел бы, чтобы эти строки кода выполнялись при запуске сервера (как разработка, так и производство):
from django.core import management
management.call_command('syncdb', interactive=False)
Положить его в settings.py
не работает, так как требует загрузки настроек уже.
Размещение их в представлении и внешний доступ к этому представлению также не работают, так как есть некоторые промежуточные программы, которые используют базу данных, и они не будут работать и не позволят мне получить доступ к представлению.
Поместить их в промежуточное ПО будет работать, но это будет вызываться каждый раз, когда к моему приложению обращаются. Возможным решением может быть создание промежуточного программного обеспечения, которое выполняет всю работу, а затем удаляет себя из MIDDLEWARE_CLASSES
так что это больше не называется. Могу ли я сделать это без слишком большого количества исправлений обезьян?
6 ответов
Напишите промежуточное программное обеспечение, которое делает это в __init__
а потом поднять django.core.exceptions.MiddlewareNotUsed
от __init__
, django удалит его для всех запросов:). __init__
Кстати, вызывается при запуске, а не по первому запросу, поэтому он не заблокирует вашего первого пользователя.
Говорят о добавлении сигнала запуска, но он скоро будет недоступен (например, основная проблема - когда этот сигнал должен быть отправлен)
Связанный билет: https://code.djangoproject.com/ticket/13024
Обновление: Django 1.7 включает в себя поддержку этого. ( Документация, связанная с тикетом)
В Django 1.7+, если вы хотите запустить код запуска и
1. Избегайте запуска в миграциях, make-миграциях, сеансах оболочки,...
2. Избегайте запуска его дважды или более
Решение будет:
файл: myapp/apps.py
from django.apps import AppConfig
def startup():
# startup code goes here
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = "My Application"
def ready(self):
import os
if os.environ.get('RUN_MAIN'):
startup()
файл: myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
Этот пост использует предложения от @Pykler и @bdoering
Если вы использовали 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)
# Your line here.
django.core.management.call_command('syncdb', interactive=False)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Вы можете создать собственную команду и написать свой код в функции handle. подробности здесь https://docs.djangoproject.com/en/dev/howto/custom-management-commands/
Затем вы можете создать сценарий запуска, который запускает сервер django, а затем выполняет вашу новую пользовательскую команду.
Если вы используете mod_wsgi, вы можете поместить его в приложение wsgi start
Вот как я работаю с отсутствующим сигналом запуска для Django: https://github.com/lsaffre/djangosite/blob/master/djangosite/models.py Код, который вызывается там, специфичен для моего проекта djangosite, но трюк, чтобы вызвать его, написав специальное приложение (основанное на идее Росса Макфарланда), должен работать в других средах. Люк