В django, как мне вызвать подкоманду 'syncdb' из сценария инициализации? - PullRequest
45 голосов
/ 16 августа 2010

Я новичок в python и django, и, следуя книге Django , я узнал о команде 'python manage.py syncdb', которая генерировала для меня таблицы базы данных. В среде разработки я использую sqlite в базе данных памяти, поэтому он автоматически стирается при каждом перезапуске сервера. Итак, как мне написать эту команду 'syncdb'? (Должно ли это быть сделано внутри файла 'settings.py'?)

ПОЯСНЕНИЯ

OP использует базу данных в памяти, которую необходимо инициализировать в начале любого процесса, работающего с моделями Django, определенными для этой базы данных. Каков наилучший способ обеспечить инициализацию базы данных (один раз за запуск процесса). Это может быть для запуска тестов или запуска сервера через manage.py runserver или через процесс веб-сервера (например, с помощью WSGI или mod_python).

Ответы [ 5 ]

78 голосов
/ 16 августа 2010

Все команды управления Django могут быть доступны программно :

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

В идеале вы должны использовать сигнал pre-init для runserver, чтобы активировать это, но такой сигнал не существует .Так что, на самом деле, если бы вы были с вами, я бы создал собственную команду управления, такую ​​как runserver_newdb, и выполнял бы ее внутри:

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

См. документацию для получения дополнительной информации о написании пользовательских команд управления.

9 голосов
/ 16 августа 2010

В соответствии с предложением " Где разместить код запуска Django? ", вы можете использовать промежуточное ПО для кода запуска. Документы Django здесь .

Например (не проверено):

startup.py:

from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
from django.core.management import call_command

class StartupMiddleware(object):
    def __init__(self):
        # The following db settings name is django 1.2.  django < 1.2 will use settings.DATABASE_NAME
        if settings.DATABASES['default']['NAME'] == ':memory:':
            call_command('syncdb', interactive=False)

        raise MiddlewareNotUsed('Startup complete')

и в ваших настройках.py:

 MIDDLEWARE_CLASSES = (
     'your_project.middleware.startup.StartupMiddleware',

     # Existing middleware classes here
 )
5 голосов
/ 16 августа 2010

Обновление

Я добавил скрипт с именем run.sh в корневой каталог проекта. Это работало для меня с базой данных SQLite:

#!/usr/bin/python
from django.core.management import call_command
call_command('syncdb')
call_command('runserver')

Оригинальный ответ

Я не уверен, что понимаю, что вы подразумеваете под «написанием сценария команды syncdb». Вы обычно выполняете python manage.py syncdb из командной строки. Обычно это делается после добавления новых моделей. В случае, если вы хотите, чтобы вы легко достигли этого, используя простой скрипт оболочки. Я не вижу причин помещать (или вызывать) syncdb изнутри settings.py.

Не могли бы вы добавить больше деталей к вашему вопросу? Добавьте контекст и объясните, что именно вы пытаетесь сделать?

0 голосов
/ 27 февраля 2019

@ Ответ Дэниела Нааба, а также документа на официальном сайте не предназначен для выполнения команд управления в качестве точки входа.

Когда вы хотите использовать команду управления в качестве точки входа в среде управляемого облака, напримерФункции AWS Lambda или Google Cloud вы можете посмотреть на manage.py и попробовать что-то подобное.

import os
from django.core.management import execute_from_command_line

def publishing_fn(data, context):
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'YOURAPP.settings')
    # The first argument is "manage.py" when it's run from CLI.
    # It can be an empty string in this case
    execute_from_command_line(['', 'COMMAND', 'ARGS...'])
0 голосов
/ 16 августа 2010

Вы можете создать новый скрипт, который вы вызываете вместо manage.py, который вызывает manage.py:

from subprocess import call
call(["python", "manage.py", "syncdb"])
call(["python", "manage.py", "runserver"])

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

call(["python", "manage.py", "syncdb", "--noinput"])

Я предполагаю, что вы пытаетесь создать свою БД и затем запускать сервер с помощью одной команды каждый раз.

...