매일 오전 7시에 메일을 보내줘야하는 기능을 구현하려 한다.
열심히 구글링을 한 결과 crontab을 사용해보려고 한다.
그런데 Windows에서는 crontab 사용이 불가능하다고 한다...
다시 구글링을 한 결과
APScheduler(Advanced Python Scheduler)라는 것을 찾아냈다.
일단 설치를 해줬다.
pip install apscheduler
잘 설치가 된 것 같다.
이제 settings.py 에 설정을 입력해준다.
#myproject/myproject/settings.py
INSTALLED_APP = [
...
'django_apscheduler',
...
]
APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a" # Default
SCHEDULER_DEFAULT = True
근데 노란줄이 쳐지면서 없는 모듈이라는 얘기를 한다.
또 다시 구글링을 한 결과
pip install django-apscheduler
위와 같이 설치를 해야한다. APScheduler 말고 다른 라이브러리도 같이 설치되는 것 같은데 뭔지는 잘 모르겠다.
설치를 하고나니 노란줄이 사라졌다.
이제 작동될 코드를 만들어 봐야겠다.
기본적으로 메일을 보낼 것이니 mail앱 내에, 즉 myproject/mail 아래에서 돌아가도록 만들 것이다.
# myproject/mail/views.py
...
from django.conf import settings
import datetime
...
def send_mail():
#날짜 셋팅
now = datetime.datetime.now()
nowDate = now.strftime('%Y-%m-%d')
date = nowDate.split('-')
subject = '[자동]' + date[0] + '년 ' + date[1] + '월 ' + date[2] + '일 메일을 보냅니다.'
all_post = Post.objects.all()
todaylist = []
for post in all_post:
todaylist.append(post)
if str(post.pub_date) < str(now - datetime.timedelta(1)):
break
for post in todaylist:
writer = post.account
to = [writer.email for writer in writer.subscribed.all()]
context = post.content
today_mail = EmailMessage(subject=subject, body=context, from_email = settings.DEFAULT_FROM_EMAIL, to=to)
today_mail.send()
날짜 셋팅은 별로 의미는 없다.
보내는 시간 기준 24시간 전부터 지금까지의 글을 보내기 위해서 위와 같이 설정했다.
이제 send_mail이 실행되도록 operator.py를 만들어 줄 것이다.
# myproject/mail/operator.py
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
from django.conf import settings
from apscheduler.executors.pool import ProcessPoolExecutor, ThreadPoolExecutor
from django_apscheduler.jobstores import register_events, DjangoJobStore
import time
from .views import send_mail
def start():
scheduler=BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), 'djangojobstore')
register_events(scheduler)
@scheduler.scheduled_job('cron', minute = '*/5', name = 'auto_mail')
def auto_mail():
send_mail()
scheduler.start()
위 설정에서는 일단 잘 날아가는지 확인하기 위해서 'cron' 설정을 minute = '*/5'로 했다.
위와 같이 설정하면 5배수분에 작동한다.
그리고 마지막으로 apps.py에서 시작 설정을 해준다.
#myproject/mail/apps.py
from django.apps import AppConfig
from django.conf import settings
class MailConfig(AppConfig):
name = 'mail'
def ready(self):
if settings.SCHEDULER_DEFAULT:
from . import operator
operator.start()
settings.py에서 SCHEDULER_DEFAULT = True로 해준 이유가 자동으로 시작하란 뜻이다.
False로 해놓으면 스케쥴러가 작동하지 않는다.
전부 설정한 듯 하다. 이제 잘 되는지 확인을 해본다.
python manage.py runserver
에러가 난다.
INSTALLED_APP에 MailConfig가 없다. 그냥 'mail'로 앱을 등록해놓았다.
#myproject/myproject/settings.py
INSTALLED_APP = [
...
'MailConfig',
...
]
다시 runserver를 해본다.
서버는 돌아간다.
근데 문제점이 생겼다.
메일이 엄청나게 많이온다. 똑같은 메일들이 수십통씩 온다. 이유를 알 수가 없다.
Scheduler를 수정해본다.
BackgroundScheduler를 BlockingScheduler로 바꿔보았다.
다시 runserver를 해보았다.
한통씩 날아오기 시작했다! 근데 서버가 켜지지 않고 메일만 날아온다! 이건 쓸 수가 없다.
BlockingScheduler는 단일 스케쥴러라고 한다.
다시 BackgroundScheduler로 바꿔주고 서버를 돌릴 때 다음과 같이 실행한다.
python manage.py runserver --noreload
차분하게 메일을 기다려보니 메일이 한통씩 온다.
뭔가 성공한 것 같은데 무작정 코드만 땡겨와서 성공시킨 것이라 되고 안되고의 이유를 전혀 모르겠다.
공부해봐야겠다.
'Web > Django' 카테고리의 다른 글
[Django] Riot API로 전적조회 사이트 만들기 - 1 (0) | 2020.10.07 |
---|