Django가 ONCE 만 시작할 때 코드를 실행 하시겠습니까?
시작시 한 번만 실행하여 다른 임의의 코드를 초기화하려는 Django Middleware 클래스를 작성 중입니다. 여기 에 sdolan이 게시 한 매우 훌륭한 솔루션을 따랐 지만 "Hello"메시지가 터미널에 두 번 출력됩니다 . 예 :
from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
class StartupMiddleware(object):
def __init__(self):
print "Hello world"
raise MiddlewareNotUsed('Startup complete')
Django 설정 파일에서 클래스가 MIDDLEWARE_CLASSES
목록에 포함되어 있습니다.
그러나 runserver를 사용하여 Django를 실행하고 페이지를 요청하면 터미널에 도착합니다.
Django version 1.3, using settings 'config.server'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Hello world
[22/Jul/2011 15:54:36] "GET / HTTP/1.1" 200 698
Hello world
[22/Jul/2011 15:54:36] "GET /static/css/base.css HTTP/1.1" 200 0
"Hello world"가 두 번 인쇄되는 이유가 있습니까? 감사.
Pykler의 답변 아래 업데이트 : Django 1.7에 이제 후크가 있습니다.
이런 식으로하지 마십시오.
한 번의 시작으로 "미들웨어"를 원하지 않습니다.
최상위 레벨에서 코드를 실행하려고합니다 urls.py
. 해당 모듈을 가져 와서 한 번 실행합니다.
urls.py
from django.confs.urls.defaults import *
from my_app import one_time_startup
urlpatterns = ...
one_time_startup()
업데이트 : Django 1.7에는 이제이 후크가 있습니다.
파일: myapp/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = "My Application"
def ready(self):
pass # startup code here
파일: myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
장고 <1.7
첫 번째 답변은 더 이상 작동하지 않는 것 같습니다. urls.py는 첫 번째 요청시로드됩니다.
최근에 작동 한 것은 시작 코드를 INSTALLED_APPS init .py 중 하나에 넣는 것입니다.myapp/__init__.py
def startup():
pass # load a big thing
startup()
./manage.py runserver
...를 사용할 때 이것은 두 번 실행되지만 runserver에는 모델을 먼저 검증하는 트릭이 있습니다 ... 정상 배포 또는 runserver 자동 다시로드 할 때도 한 번만 실행됩니다.
이 질문은 Django> = 1.4에서 작동하는 Django 프로젝트 의 블로그 게시물 진입 점 후크 에서 잘 대답됩니다 .
Basically, you can use <project>/wsgi.py
to do that, and it will be run only once, when the server starts, but not when you run commands or import a particular module.
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
# Run startup code!
....
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
If it helps someone, in addition to pykler's answer, "--noreload" option prevents runserver from executing command on startup twice:
python manage.py runserver --noreload
But that command won't reload runserver after other code's changes as well.
As suggested by @Pykler, in Django 1.7+ you should use the hook explained in his answer, but if you want that your function is called only when run server is called (and not when making migrations, migrate, shell, etc. are called), and you want to avoid AppRegistryNotReady exceptions you have to do as follows:
file: myapp/apps.py
import sys
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'my_app'
def ready(self):
if 'runserver' not in sys.argv:
return True
# you must import your modules here
# to avoid AppRegistryNotReady exception
from .models import MyModel
# startup code here
Note that you cannot reliability connect to the database or interact with models inside the AppConfig.ready
function (see the warning in the docs).
If you need to interact with the database in your start-up code, one possibility is to use the connection_created
signal to execute initialization code upon connection to the database.
from django.dispatch import receiver
from django.db.backends.signals import connection_created
@receiver(connection_created)
def my_receiver(connection, **kwargs):
with connection.cursor() as cursor:
# do something to the database
Obviously, this solution is for running code once per database connection, not once per project start. So you'll want a sensible value for the CONN_MAX_AGE
setting so you aren't re-running the initialization code on every request. Also note that the development server ignores CONN_MAX_AGE
, so you WILL run the code once per request in development.
99% of the time this is a bad idea - database initialization code should go in migrations - but there are some use cases where you can't avoid late initialization and the caveats above are acceptable.
if you want print "hello world" once time when you run server, put print ("hello world") out of class StartupMiddleware
from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
class StartupMiddleware(object):
def __init__(self):
#print "Hello world"
raise MiddlewareNotUsed('Startup complete')
print "Hello world"
참고URL : https://stackoverflow.com/questions/6791911/execute-code-when-django-starts-once-only
'programing tip' 카테고리의 다른 글
http 오류 503 서비스를 사용할 수 없습니다. (0) | 2020.06.13 |
---|---|
Homebrew의 PATH를 수정하는 방법? (0) | 2020.06.13 |
파일이 이미 존재하는 경우이를 제거하는 쉘 스크립트 (0) | 2020.06.13 |
문자열을 정규식으로 보간 (0) | 2020.06.13 |
가변 길이 문자열에 대한 더 나은 유사성 순위 알고리즘 (0) | 2020.06.13 |