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

코변·2022년 7월 25일
0

신고기능

목록 보기
2/2

다른 유저에게 욕설을 사용한 유저를 신고하는 기능을 만들었다. 기능은 만들었는데 어떤 기준으로 신고된 유저들을 다룰지 난감했다.

우선 코테를 준비하면서 봤던

2022 KAKAO BLIND RECRUITMENT 신고 결과 받기를 참조하여 로직을 구성해보았다.

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

우선 유저가 한번에 한명의 유저를 신고하려면

class Report(models.Model):
    report_user = models.ForeignKey("User", on_delete=models.CASCADE)
    reported_user = models.ForeignKey("ReportedUser", on_delete=models.CASCADE)
    report_reason = models.CharField(max_length=150)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["report_user", "reported_user"], name="only_one_report"
            )
        ]

위와 같이 uniqueConstraint를 통해서 같은 유저를 여러번 신고할 수 없도록 설정해준다.

  1. k번 신고당한 유저를 정지시키기 위해서는 annotate와 Count를 통해 reported유저의 수를 세고 filter와 __gte를 활용해 k번 이상 신고된 유저를 걸러준다.
ReportedUserModel.objects.select_related("user")
        .annotate(reported_cnt=Count("report"))

위 코드와 같이 annotate를 활용해서 report가 몇 번 되었는지 Count 해주었고

 .filter(reported_cnt__gte=REPORT_CONDITION_CNT)

그 뒤에 filter를 통해서 카운트 값이 REPORT_CONDITION_CNT 보다 크다면 가져올 수 있도록 하였다.

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

selected_related를 활용하여 user값을 미리 불러와 .user를 조회할 때마다 query를 보내지 않도록 하여 쿼리 수를 줄였다.

profile
내 것인 줄 알았으나 받은 모든 것이 선물이었다.

0개의 댓글