Django アプリケーションの開発プロセスでは、開発者モードを使用してサービスを開始するのが特に便利です。サービスを実行するために必要なのは python manage.py runserver だけです。これは、非常にユーザーフレンドリーな自動リロード メカニズムを提供します。プログラムを手動で再起動してコードを変更し、フィードバックを確認できます。初めて触れたときは、「もっと使いやすい機能だ」という印象で、特に高度な技術だとは思いませんでした。後で時間があるときに、このオートリロードを実装する場合はどうするかを考えましたが、ずっと考えてもわかりませんでした。私の最初の反応は、自分には野心がありすぎてスキルが不足しているということでした。そこで私は、Django が自動リロードを実装する方法を少し時間をかけて研究し、すべてのステップのソース コードを確認しました。
1. Runserver コマンド。本題に入る前に、runserver コマンドの実行方法については実際には意味のないことがたくさんありますが、本題とはほとんど関係がないので、簡単に説明します。
コマンド ラインで python manage.py runserver と入力した後、 Django は runserver コマンドの実行モジュールを探し、最終的に
#django\contrib\staticfiles\management\commands\runserver.pyfrom django.core.management.commands.runserver import \ Command as RunserverCommandclass Command(RunserverCommand): help = "Starts a lightweight Web server for development and also serves static files."
#django\core\management\commands\runserver.pyclass Command(BaseCommand): def run(self, **options): """ Runs the server, using the autoreloader if needed """ use_reloader = options['use_reloader'] if use_reloader: autoreload.main(self.inner_run, None, options) else: self.inner_run(None, **options)
実際、autoreload.main のパラメータから、autoreload のメカニズムがこれらのカプセル化に含まれていることがわかります。
#django\utils\autoreload.py:def main(main_func, args=None, kwargs=None): if args is None: args = () if kwargs is None: kwargs = {} if sys.platform.startswith('java'): reloader = jython_reloader else: reloader = python_reloader wrapped_main_func = check_errors(main_func) reloader(wrapped_main_func, args, kwargs)
#django\utils\autoreload.py:def python_reloader(main_func, args, kwargs): if os.environ.get("RUN_MAIN") == "true": thread.start_new_thread(main_func, args, kwargs) try: reloader_thread() except KeyboardInterrupt: pass else: try: exit_code = restart_with_reloader() if exit_code < 0: os.kill(os.getpid(), -exit_code) else: sys.exit(exit_code) except KeyboardInterrupt: pass
#django\utils\autoreload.py:def restart_with_reloader(): while True: args = [sys.executable] + ['-W%s' % o for o in sys.warnoptions] + sys.argv if sys.platform == "win32": args = ['"%s"' % arg for arg in args] new_environ = os.environ.copy() new_environ["RUN_MAIN"] = 'true' exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ) if exit_code != 3: return exit_code
の説明を見てください。
_spawnvef(mode, file, args, env, execve)
#django\utils\autoreload.py:def python_reloader(main_func, args, kwargs): if os.environ.get("RUN_MAIN") == "true": thread.start_new_thread(main_func, args, kwargs) try: reloader_thread() except KeyboardInterrupt: pass else: try: exit_code = restart_with_reloader() if exit_code < 0: os.kill(os.getpid(), -exit_code) else: sys.exit(exit_code) except KeyboardInterrupt: pass
#django\utils\autoreload.py:from django.utils.six.moves import _thread as thread
[codeblock six]#django\utils\six.pyclass _SixMetaPathImporter(object):"""A meta path importer to import six.moves and its submodules. This class implements a PEP302 finder and loader. It should be compatible with Python 2.5 and all existing versions of Python3"""官网说明:# https://pythonhosted.org/six/Six: Python 2 and 3 Compatibility Library Six provides simple utilities for wrapping over differences between Python 2 and Python 3. It is intended to support codebases that work on both Python 2 and 3 without modification. six consists of only one Python file, so it is painless to copy into a project.
ensure_echo_on() 実は、これは unix 風のシステムファイル処理のためのもののようですので、最初はスキップしてください。システムファイル操作に関連する変数 inotify が利用可能かどうかに基づいてファイル変更を検出する方法を選択します。
ループ中、1秒ごとにファイルのステータスをチェックします。通常のファイルに変更があった場合、プロセスは終了コード3で終了します。メインプロセスは終了コードが3であることを確認すると、子プロセスを再起動します。プロセス。 。 。 。これは、通常のファイル変更ではなく、I18N_MODIFIED (拡張子 .mo が付いているファイル変更、バイナリ ライブラリ ファイルなど) の場合は、reset_translations に関連します。これは、おそらく次回ロードされたライブラリ キャッシュをクリアすることを意味します。 。上記はオートリロード機構のプロセスです。さまざまなオペレーティング システムでのファイル変更の検出など、特に明確ではない詳細がまだいくつかありますが、これらは非常に詳細なものであり、メインのプロセスには関与しません。これを読んだ後、私はオートリロード機構の設計を頼まれたらどうするだろうかと改めて自問しました。私の答えは、「djangoutilsautoreload.py ファイルを直接使用する」です。実際、これは非常に独立したモジュールであり、汎用の自動リロード ソリューションとして使用することもできます。
以上がDjango 開発者モードでは自動リロードはどのように実装されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。