Где разместить код запуска 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, но трюк, чтобы вызвать его, написав специальное приложение (основанное на идее Росса Макфарланда), должен работать в других средах. Люк

Другие вопросы по тегам