236일차 - 커뮤니티 앱개발 (4) - 토큰(JWT), 좋아요(Like)

2021. 8. 22. 16:00Diary/201~300

1. JWT

- model

class JwtModel(models.Model):
    class Meta:
        verbose_name = "토큰"
        verbose_name_plural = "토큰 목록"

    jwt_user_id = models.ForeignKey(MobileUserModel(), on_delete=models.CASCADE,
                                    related_name="jwt_user_id", verbose_name='토큰 소유자', null=True)
    access_token = models.TextField(null=False, blank=True, verbose_name="접근 토큰")
    access_token_time = models.CharField(max_length=100, null=False, blank=True, verbose_name="접근 토큰 유효 시간")

    created_at = models.DateTimeField(auto_now_add=True, null=False, blank=True, verbose_name="생성 날짜")
    updated_at = models.DateTimeField(auto_now=True, null=False, blank=True, verbose_name="수정 날짜")

 

- view

class JwtList(generics.ListCreateAPIView):
    queryset = JwtModel.objects.all()
    serializer_class = JwtSerializer
    ordering = ['id']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id']

    def get(self, request, *args, **kwargs):
        print(request.headers)
        try:
            if request.headers["PrivatKey"] == "Kwonputer":
                queryset = self.filter_queryset(self.get_queryset())

                page = self.paginate_queryset(queryset)
                if page is not None:
                    serializer = self.get_serializer(page, many=True)
                    return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

                serializer = self.get_serializer(queryset, many=True)
                return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

        except KeyError:
            if request.user.is_authenticated:
                if request.user.is_admin != 0:
                    return self.list(request, *args, **kwargs)
                else:
                    return redirect(reverse("accountapp:login"))
            else:
                return redirect(reverse("accountapp:login"))


@csrf_exempt
@api_view(["POST"])
def jwt_check(request):
    if simple_validation(request.headers):
        pass
    else:
        return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

    if request.method == "POST":
        print(request.body)
        try:
            temp_access_token = request.headers["AccessToken"]
            if temp_access_token:
                try:
                    jwt_model = JwtModel.objects.get(access_token=temp_access_token)
                except JwtModel.DoesNotExist:
                    return JsonResponse(json_error("E0010"), status=status.HTTP_400_BAD_REQUEST)
        except KeyError:
            return JsonResponse(json_error("E0002"), status=status.HTTP_400_BAD_REQUEST)


def access_id(access_token):
    try:
        model = JwtModel.objects.get(access_token=access_token).jwt_user_id
        return model
    except JwtModel.DoesNotExist or AssertionError:
        return False


def validation(headers):
    try:
        if headers["PrivatKey"] != "비~밀ㅎ":
            return False

    except KeyError:
        return False

    try:
        temp_request_access_token = headers["AccessToken"]
        temp_rat_check = access_id(temp_request_access_token)
        if temp_rat_check is False:
            return False
    except KeyError:
        return False

    return True


def simple_validation(headers):
    try:
        if headers["PrivatKey"] != "비~밀ㅎ":
            return False

    except KeyError:
        return False

    return True

 

2. Like

- model

class BoardLikeModel(models.Model):
    user = models.ForeignKey(MobileUserModel, on_delete=models.CASCADE, related_name="like_board_user")
    board = models.ForeignKey(BoardModel, on_delete=models.CASCADE, related_name="like_board")

    class Meta:
        unique_together = ('user', 'board')


class CommentLikeModel(models.Model):
    user = models.ForeignKey(MobileUserModel, on_delete=models.CASCADE, related_name="like_comment_user")
    comment = models.ForeignKey(CommentModel, on_delete=models.CASCADE, related_name="like_comment")

    class Meta:
        unique_together = ('user', 'comment')

 

- view

class BoardLikeList(generics.ListCreateAPIView):
    queryset = BoardLikeModel.objects.all()
    serializer_class = BoardLikeSerializer
    ordering = ['-id']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id']

    def get(self, request, *args, **kwargs):
        print(request.headers)
        try:
            if request.headers["PrivatKey"] == "ㅎㅎ":
                queryset = self.filter_queryset(self.get_queryset())

                page = self.paginate_queryset(queryset)
                if page is not None:
                    serializer = self.get_serializer(page, many=True)
                    return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

                serializer = self.get_serializer(queryset, many=True)
                return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

        except KeyError:
            if request.user.is_authenticated:
                if request.user.is_admin != 0:
                    return self.list(request, *args, **kwargs)
                else:
                    return redirect(reverse("accountapp:login"))
            else:
                return redirect(reverse("accountapp:login"))

    def post(self, request, *args, **kwargs):
        if validation(request.headers):
            pass
        else:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

        try:
            ck = access_id(request.headers["AccessToken"])
            temp_board_id = request.data["board_id"]
            temp_board_model = BoardModel.objects.get(id=temp_board_id)
            if ck is not False:
                like_board_model = BoardLikeModel.objects.filter(user_id=ck, board_id=temp_board_model)
                if like_board_model.count() >= 1:
                    content = {"id": like_board_model.latest("id").pk, "user": ck.pk, "board": temp_board_model.pk}
                    like_board_model.delete()
                    temp_board_model.board_like_count -= 1
                    temp_board_model.save()
                    return JsonResponse(json_success("S0003", content), status=status.HTTP_200_OK)
                else:
                    temp_board_model.board_like_count += 1
                    temp_board_model.save()

                user_model = ck
                request.data.update(user=user_model.pk)
                request.data.update(board=temp_board_model.pk)
        except MobileUserModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except BoardModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except BoardLikeModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        return JsonResponse(json_success("S0001", serializer.data), status=status.HTTP_200_OK)


class CommentLikeList(generics.ListCreateAPIView):
    queryset = CommentLikeModel.objects.all()
    serializer_class = CommentLikeSerializer
    ordering = ['-id']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id']

    def get(self, request, *args, **kwargs):
        print(request.headers)
        try:
            if request.headers["PrivatKey"] == "ㅎㅎ":
                queryset = self.filter_queryset(self.get_queryset())

                page = self.paginate_queryset(queryset)
                if page is not None:
                    serializer = self.get_serializer(page, many=True)
                    return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

                serializer = self.get_serializer(queryset, many=True)
                return JsonResponse(json_success("S0004", serializer.data), status=status.HTTP_200_OK)

        except KeyError:
            if request.user.is_authenticated:
                if request.user.is_admin != 0:
                    return self.list(request, *args, **kwargs)
                else:
                    return redirect(reverse("accountapp:login"))
            else:
                return redirect(reverse("accountapp:login"))

    def post(self, request, *args, **kwargs):
        if validation(request.headers):
            pass
        else:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

        try:
            ck = access_id(request.headers["AccessToken"])
            temp_comment_id = request.data["comment_id"]
            temp_comment_model = CommentModel.objects.get(id=temp_comment_id)
            if ck is not False:
                like_comment_model = CommentLikeModel.objects.filter(user_id=ck, comment_id=temp_comment_model)
                if like_comment_model.count() >= 1:
                    content = {"id": like_comment_model.latest("id").pk, "user": ck.pk, "comment": temp_comment_model.pk}
                    like_comment_model.delete()
                    temp_comment_model.comment_like_count -= 1
                    temp_comment_model.save()
                    return JsonResponse(json_success("S0003", content), status=status.HTTP_200_OK)
                else:
                    temp_comment_model.comment_like_count += 1
                    temp_comment_model.save()

                user_model = ck
                request.data.update(user=user_model.pk)
                request.data.update(comment=temp_comment_model.pk)
        except MobileUserModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except BoardModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except BoardLikeModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        return JsonResponse(json_success("S0001", serializer.data), status=status.HTTP_200_OK)

 

토큰이랑 좋아요 기능을 만들었다.

토큰은 뭐 잘 될 것같고, 좋아요 기능은 추측과 상상으로만 개발해서 테스트해봐야 잘 될지 알 수 있을 것 같다.

걱정인부분은, 게시판 글이랑 댓글에 대한 좋아요 카운트를 ++ 하거나 -- 하게 알고리즘을 짰는데, 이 부분이 오류 없이 잘 작동할지는 해봐야알 것 같다. 포스트맨으로는 문제가 없었다.

 

왜 카운트로 안했냐면은 알고리즘 짜면서 느꼈는데, 생각해보니까 차후에 좋아요도 -가 될 수 있을지도 모른다는 생각에 일단 가능성을 열어둬야겠다고 생각했다. 싫어요나 그런 기능들도 있으니까...

또, 외래키로 잡을 때, CASECADE로 잡아놔서 유저계정이 삭제되면 모델도 사라지게 해놨다. 나중에 동일아이디로 유저가 가입했을 때, 문제가 생길 소지가 있어 보여서.

애초에 외래키잡는건 대부분 CASECADE로 만드는걸 선호한다. DB꼬이면 너무.. 힘들어..

그래서 좋아요 모델에 저장된 갯수로 좋아요 숫자를 카운트하게되면, 유저가 계정을 삭제했을 때, 해당 유저가 좋아요를 누른 글과 댓글은 전부 -1이 되니까, 이건 좀 아닌것같아서 ++, --로 바꿨다.