DjangoはPythonでwebアプリを作る際の代表的なライブラリです。DjangoへApshedulerというライブラリ追加して、関数を定期的に自動実行します。また、私の環境ではセオリー通りにやると、関数が二回ずつ実行される症状が発生しました。この症状はrunserverに「–noreload」とオプションを付けることで回避できます。
- VScodeでDjangoのプロジェクトスタートまで操作
- Django + Apsheduler で定期実行を行う。
- 「runserver –noreload」で、2回実行される挙動の回避
動作環境
本記事の動作環境は下記の通りです。
- windows10
- visualstudiocode1.73.1
- python 3.8
プロジェクトの作成して開発用サーバーを起動
作業フォルダ(ワークスペース)の作成
VisualStudioCodeでDjangoプロジェクトを作成し、開発用サーバーを起動します。
「C:¥python¥test」というフォルダを作成し、作成したtestフォルダを右クリックし「Codeで開く」を選択します。
もし「Codeで開く」が表示されない場合はVisualStudioCodeを再インストールしましょう。これが表示されないと非常に不便です。
仮想環境の構築
VisualStudioCodeが起動したら、次に仮想環境を構築します。
pythonはDjango以外にも様々なライブラリがあり、目的に合わせて使い分けが必要です。
仮想環境を構築せずに、いきなりDjangoやそのほかのライブラリをインストールすることもできます。この場合、ライブラリが増えてくると管理が大変で、何をインストールしたのかわからなくなってきます。使いたい用途に合わせてその都度、仮想環境を構築して、必要分だけライブラリをインストールする方が管理が簡単です。
VisualStudioCodeで「表示」→「ターミナル」と選択し、ターミナルを起動します。「C:python¥test>」と表示されるので、そこへ順番にコマンドを入力していきます。
まず下記のコマンドで仮想環境を構築します。「env」は仮想環境へつける名前なので、任意のもので結構です。「python」は環境によっては「python3」としないと動かない場合があります。
PS C:python¥test>python -m venv env
Code language: CSS (css)
次に構築した仮想環境を有効化します。ターミナルに下記のコマンドを入力します。「env」は仮想環境につけた名前によって読み替えてください。
PS C:python¥test> .\env\Scripts\Activate.ps1
Code language: CSS (css)
成功するとターミナルの左に「(env)」と表示されます。これは、envという仮想環境が有効になっていることを意味しています。
Djangoのインストール
続いて、djangoをインストールしていきます。
(env)PS C:python¥test> pip install django
Code language: CSS (css)
コマンドを入力してしばらく待つと、Djangoのインストールに成功した旨のメッセージが表示されます。
下記のコマンドを入力し、インストールできているか確認します。
(env)PS C:python¥test> pip list
Code language: CSS (css)
Djangoプロジェクトの作成と開発サーバーの起動
Djangoのプロジェクトを作成します。作成は以下のコマンドを打ち込むだけです。「testproject」は任意のもので構いません。ここで入力したものがプロジェクト名になります。成功すると、プロジェクトフォルダとその中の様々なファイルが生成されます。
(env)PS C:\python\test> django-admin startproject testproject
次に、作業フォルダをプロジェクトフォルダに変更します。下記のコマンドを入力し、「PS C:\python\test>」となっているところが「PS C:\python\test¥testproject」となればOKです。
(env)PS C:\python\test> cd .\testproject
次にアプリを作成します。下記のコマンドでアプリを作成します。成功すると、プロジェクトフォルダの中にアプリフォルダが生成されます。
(env)PS C:\python\test\testproject> python manage.py startapp testapp
Code language: CSS (css)
Djangoの開発用サーバーを起動します。下記のコマンドで開発用サーバーを起動します。この記事では、データベースの初期設定をしていないので赤文字で警告が表示されますが、データベースは使わないので無視します。
開発用サーバーの起動に成功すると、ターミナルに「Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.」と表示されます。「http~」の部分をキーボードのコントロールボタンを押しながらクリックすると、webブラウザにロケットのアニメーションが表示されます。
開発用サーバーへのアクセスが成功しました。
サーバーを停止する場合は、VisualStudioCodeで「ctrl + c」を入力します。
(env)PS C:\python\test\testproject> django-admin .\manage.py
Code language: CSS (css)
Apschedulerのインストール
ターミナルに下記のコマンドを入力して「Apscheduler」をインストールします。インスト―ルに成功しているか否かは、「pip list」で確認できます。
(env)PS C:\python\test\testproject> pip install apscheduler
(env)PS C:\python\test\testproject> pip list
Code language: PHP (php)
関数の定期実行の実装
関数の作成
簡単な関数を作成して、定期実行をテストしてみます。
「testapp」(アプリフォルダ)にapschedule.pyという名前でファイルを作成し、下記のコードを貼り付けます。
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
# 現時刻をターミナルに出力する関数
def test_func():
print ("時刻:" + str(datetime.now()) + "関数が実行されました。")
# 自動実行のための関数
def start():
scheduler = BackgroundScheduler()
scheduler.add_job(test_func, 'interval', minute=1)# 一分間隔で関数を実行
scheduler.start()
参考:実行の間隔の書き方。
下の記述方法を真似すれば、定期的な実行の間隔を好きな時間、好きな間隔に変更できます。
# 5分おきに実行
scheduler.add_job(periodic_execution, 'interval', minutes=5)
# 1時間5秒おきに実行
scheduler.add_job(periodic_execution, 'interval', hours=1, seconds=5)
# 1日おきに実行
scheduler.add_job(periodic_execution, 'interval', days=1)
# 1週間おきに実行
scheduler.add_job(periodic_execution, 'interval', weeks=1)
# 2022年4月1日19時〜20時の間、1分おきに実行
scheduler.add_job(periodic_execution, 'interval', minutes=1,
start_date="2022-04-01 19:00:00",
end_date="2022-04-01 20:00:00")
# 毎時20分に実行
scheduler.add_job(periodic_execution, 'cron', minute=20)
# 月曜から金曜の間、22時になると実行
scheduler.add_job(periodic_execution, 'cron', hour=22, day_of_week='mon-fri')
このページから参考にさせていただきました。
apps.py とsetting.pyへ書き加え
「testapp」(アプリフォルダ)にapps.pyというアプリの設定ファイルがあります。ここへ定期実行のための記述を追記します。
from django.apps import AppConfig
class TestappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'testapp'
def ready(self): # 追記 必ず既存のclassモジュールの中に記述する。インデントに注意
from .apschedule import start #追記 インポート元として前述のapsheduleで作成したstart関数を指定する。
start() #追記 インポートしたstart関数を実行
次に「testproject」(プロジェクトフォルダ)setting.pyにはアプリケーション追加します。
「setting.py」の中から「INSTALLED_APPS」の記述を探して、その中にアプリのConfigファイルを記述します。
どのDjangoの入門書に必ず書いてある、ごくごく一般的な記述です。
これで、Djangoを使った定期的な関数実行の準備が完了です。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'testapp.apps.TestappConfig', # アプリフォルダ内の「TestappConfig」を指定
]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
定期実行の動作確認
再び、「runserver」で開発用サーバーを立ち上げ、定期な自動実行の動作を確認しましょう。狙った通りに一分ごとに関数が実行され、ターミナルに時刻が表示されます。
ただし、私の環境の場合、一分ごとに関数が二回ずつ実行される事態になってしまいました。
runserverで定期実行が2回実行される挙動の回避
2回実行される原因
細かい理由はわかりませんが、Djangoのrunserverでは、プロセスが二つ立ち上がることに原因があるようです。
「– noreload」で2回実行される挙動を回避
この挙動は、開発用サーバーを立ち上げる際に「– noreload」とオプションを付けることで回避できます。
(test) PS C:\python\test\testproject> python manage.py runserver --noreload
Code language: CSS (css)
–noreloadオプションはこちらのブログにも開設がありました。
VScodeのデバックを使う場合
visual studio codeでDjangoの開発をする際は、デバック機能を活用して、開発用サーバーを立ち上げている人が多いかと思います。この場合は、デバックの設定が記述されている「launch.json」の記述を書き換える必要があります。
「configrations」→「args」 のリスト中に、「“–noreload”」を書き加えます。
これにより、デバック機能からrunserverをする場合でも、「–noreload」オプションを付けたことになります。
まとめ
この記事では、Djangoを使ったwebアプリで、定期的に関数を実行する方法を紹介しました。
・「Apscheduler」というライブラリを使えば、関数の定期的な実行が簡単にできる。
・定期的な実行を開発用サーバーでテストする場合は、「–noreload」オプションを付ける。
この二点を覚えておくとよいでしょう。
コメント