django-apscheduler를 통해서 유저 신고기능 구현 -2

코변·2022년 7월 27일
1

신고기능

목록 보기
1/2

첫번째 시리즈에서 2까지 적었으므로 이어서 3부터 쓰려고 한다.

  1. 유저는 한번에 한 명의 유저만 신고할 수 있다.
    (신고한 유저와 신고를 당한 유저가 담긴 report는 unique하다)
  2. k번 신고당한 유저는 정지를 당한다.
  3. (현재는 유저가 많지 않기에) 일주일에 한 번 k번 이상 신고된 유저를 검사한다.
  4. k번 이상 신고된 유저들을 모아 is_active값을 False로 바꾸어 준다.
  5. report 유저 db값을 초기화 시켜준다.

3. (현재는 유저가 많지 않기에) 일주일에 한 번 k번 이상 신고된 유저를 검사한다.

일정한 스케줄에 따라서 보내야 하기 때문에 python django schedule이라는 검색어로 검색을 했고 django-apscheduler를 찾았다.

각종 블로그와 스택오버 플로우를 통해서 사용방법을 검색한 결과

  1. pip install 을 통해 다운로드를 받는다.
pip install django-apscheduler
  1. 인스톨드앱에 apscheduler를 추가해준다,.
INSTALLED_APPS = (
    "django_apscheduler",
)
  1. settings.py에 초기 설정 수정이 가능하다.
ex:
APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a"
APSCHEDULER_RUN_NOW_TIMEOUT = 25
  1. 기존의 apscheduler를 사용하면 jobstore에 장고를 선언해주어야 하지만 디폴트로 설정되어 있어 바로 사용하면 된다.
  2. apscheduler 모듈을 임포트해준다.
  • 서버에서 백그라운드로 실행하고 싶기 때문에 backgroundscheduler를 가져왔다.
  • 기준이 되는 시간에 함수를 실행하고 싶기 때문에 CronTrigger를 가져왔다.
  • 이벤트들을 등록하기 위해서 register_events를 가져왔다.
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from django.conf import settings
from django_apscheduler.jobstores import register_events

from user.services.report_service import get_reported_user_over_condition_cnt

장황하게 설명한 것 치고는 코드는 간단하다.

def start():
    scheduler = BackgroundScheduler(timezone=settings.TIME_ZONE)
    register_events(scheduler)

    scheduler.add_job(
        get_reported_user_over_condition,
        trigger=CronTrigger(day_of_week="sun", hour="20", minute="06"),
        max_instances=1,
        name="check_reported_user",
    )

    scheduler.start()

백그라운드 스케쥴러를 등록해주고 start라는 함수로 감싼다. 그 안에 add_job함수로 내가 미리 만들어둔 함수, 트리거, 인스턴스를 몇개 정도 사용할건지를 입력해주면 된다.

4. k번 이상 신고된 유저들을 모아 is_active값을 False로 바꾸어 준다.

5. report 유저 db값을 초기화 시켜준다.

마지막으로 저번 시리즈에서 만들었던 함수에 마지막 몇 줄의 로직을 추가해주면 신고 기능은 완성된다!

def get_reported_user_over_condition() -> None:
    """
    condition 이상으로 신고된 유저를 찾고 그 유저의 active값을 변경하는 함수
    """
    report_cnt_over_condition_reported_users = list(
        ReportedUserModel.objects.select_related("user")
        .annotate(reported_cnt=Count("report"))
        .filter(reported_cnt__gte=REPORT_CONDITION_CNT)
    )

    for reported_user in report_cnt_over_condition_reported_users:
        reported_user.user.is_active = False
        reported_user.user.save()

    ReportModel.objects.all().delete() 시켜준다.
profile
내 것인 줄 알았으나 받은 모든 것이 선물이었다.

0개의 댓글