TIL(Today I Learned)
6월 19일 TIL - 스케쥴러
Hyerin P.
2023. 6. 19. 21:45
▷ 오늘의 배움
📖 특정 시간마다 함수 실행시키기: apscheduler
💬 스케줄 수행 방식 3가지
Cron 방식 - Cron 표현식으로 수행
Date 방식 - 특정 날짜에 수행
Interval 방식 - 일정 주기로 수행
✏️ 설치하기
pip install APScheduler==3.2.0
✏️ 사용하기
from apscheduler.schedulers.background import BackgroundScheduler
# 스케줄러 정의
scheduler = BackgroundScheduler()
# 데코레이터로 스케줄러 사용
@sched.scheduled_job('cron', hour='12', minute='30', id='my_job_id')
def myfunc():
print('hello world!')
# 스케줄러를 사용할 함수 추가
scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id')
# 스케줄러 시작
sched.start()
▷ 오늘의 시도
메인페이지에 띄워지는 게시글들은 프론트에서 백 검색 url로 데이터를 가져오는 형식을 취하고 있었다. 하지만 이러면 주마다 또는 하루마다 프론트에서 요청하는 쿼리를 일일이 수정시켜야만 했다. 그래서 백에서 랜덤으로 데이터들을 뽑아내어 보내주는 뷰를 새로 생성하였다. 하지만 이렇게 했을 때 새로고침 할 때마다 출력되는 데이터가 달라져 어떻게 해야하나 싶었다. 특정시간마다 함수를 실행시켜야 했는데 팀장님께서 APScheduler라는 라이브러리를 알려주셨다. 이 라이브러리의 사용법은 위에 적어놓았다. 이 라이브러리를 이용하여 하루에 한번씩 태그를 선택하고 그 태그에 해당하는 게시물들을 반환할 수 있는 뷰를 짜고자 하였다. 태그가 너무 무작위로 선택되면 안되기 때문에 주간태그라는 모델을 만들어 어드민에서 관리 할 수 있게 하였다. 하루에 한번씩 태그가 선택되는 함수, 즉 일주일치의 태그 객체가 담긴 데이터베이스가 필요했다. 그래서 무작위로 주간 태그 객체 7개를 작성하였고 하루에 한번씩 태그가 하나씩 교체되도록 작성해주었다.
scheduler = BackgroundScheduler()
# 7개의 객체가 있는 데이터베이스에서 오늘의 태그를 가져오면 전날 사용된 태그는 버리고 새로운 객체를 생성한다.
def get_weekly_tags():
weekly_tags = WeeklyTags.objects.all()
weekly_tags[0].delete()
queryset = Tag.objects.filter(Q(db_status=1))
random_tags = random.choice(list(queryset))
WeeklyTags.objects.create(tag = random_tags)
scheduler.add_job(get_weekly_tags, 'cron', hour=0, id="rand_3")
scheduler.start()
class ArticleRandomView(generics.ListAPIView):
"""
여러개의 게시물을 무작위로 반환합니다.
태그를 무작위로 하나 선택하여 그 태그가 달린 게시물들을 반환합니다.
input: 쿼리=option
ouput: 무작위 게시물들
"""
serializer_class = ArticleSerializer
def get_queryset(self):
# 게시물 임의 선택
if self.request.query_params.get("option") == "article":
return random_article
# 임의의 태그 선택
# 주간 태그의 첫번째 객체를 가져와 그 태그가 포함된 게시글들을 반환한다.
elif self.request.query_params.get("option") == "tag":
queryset_list = []
weekly_tags=WeeklyTags.objects.all()
tag = weekly_tags[0]
taglist = tag.tag.taglist_set.all().order_by("-created_at")
for b in taglist:
queryset_list.append(b.article)
return queryset_list