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()

Cron 방식으로 설정할 때 파라미터
Interval 방식으로 설정할 때 파라미터

▷ 오늘의 시도

메인페이지에 띄워지는 게시글들은 프론트에서 백 검색 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