다른 유저에게 욕설을 사용한 유저를 신고하는 기능을 만들었다. 기능은 만들었는데 어떤 기준으로 신고된 유저들을 다룰지 난감했다.
우선 코테를 준비하면서 봤던
2022 KAKAO BLIND RECRUITMENT 신고 결과 받기를 참조하여 로직을 구성해보았다.
우선 유저가 한번에 한명의 유저를 신고하려면
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를 통해서 같은 유저를 여러번 신고할 수 없도록 설정해준다.
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를 보내지 않도록 하여 쿼리 수를 줄였다.