235일차 - 커뮤니티 앱개발 (3) : 게시판(Board) 백엔드 개발

2021. 8. 21. 21:23Diary/201~300

1. StartApp

- accountapp

- boardapi

- certapi

- chatapi

- commonapi

- infoapi

- jwtapi

- likeapi

- showapp

 

2. Board (게시판)

- model

class BoardModel(models.Model):
    class Meta:
        verbose_name = "게시판"
        verbose_name_plural = "게시판 목록"

    board_user_id = models.ForeignKey(MobileUserModel(), on_delete=models.CASCADE, null=True, blank=True,
                                      related_name="board_user_id", verbose_name='글 소유자')
    board_username = models.CharField(max_length=30, null=True, blank=True, verbose_name="작성자 아이디")
    board_user_type = models.CharField(max_length=30, null=True, blank=True, verbose_name="작성자 MBTI")
    board_nickname = models.CharField(max_length=30, null=True, blank=True, verbose_name="작성자 닉네임")
    board_profile = models.ImageField(null=True, blank=True, verbose_name="작성자 프로필")
    board_title = models.CharField(max_length=100, null=True, blank=True, verbose_name="글 제목")
    board_content = models.TextField(null=True, blank=True, verbose_name="글 내용")
    board_type = models.CharField(max_length=100, null=True, blank=True, verbose_name="글 유형")
    board_like_count = models.IntegerField(null=True, blank=True, default=0, 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="수정 날짜")


class CommentModel(models.Model):
    class Meta:
        verbose_name = "댓글"
        verbose_name_plural = "댓글 목록"

    comment_user_id = models.ForeignKey(MobileUserModel(), on_delete=models.CASCADE, null=True, blank=True,
                                        related_name="comment_user_id", verbose_name='댓글 소유자')
    board_id = models.ForeignKey(BoardModel(), on_delete=models.CASCADE, related_name="used_board_comment_id",
                                 verbose_name='글 번호', null=True)
    comment_username = models.CharField(max_length=30, null=True, blank=True, verbose_name="댓글 작성자")
    comment_user_type = models.CharField(max_length=30, null=True, blank=True, verbose_name="작성자 MBTI")
    comment_nickname = models.CharField(max_length=30, null=True, blank=True, verbose_name="작성자 닉네임")
    comment_profile = models.ImageField(null=True, blank=True, verbose_name="작성자 프로필")
    comment_title = models.CharField(max_length=100, null=True, blank=True, verbose_name="제목")
    comment_content = models.TextField(null=True, blank=True, verbose_name="내용")
    comment_like_count = models.IntegerField(null=True, blank=True, default=0, verbose_name="좋아요 개수")
    created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name="생성 날짜")
    updated_at = models.DateTimeField(auto_now=True, null=True, blank=True, verbose_name="수정 날짜")

 

- view

class BoardList(generics.ListCreateAPIView):
    queryset = BoardModel.objects.all()
    serializer_class = BoardSerializer
    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"])
            if ck is not False:
                user_model = ck
                request.data.update(board_user_id=user_model.pk)
                request.data.update(board_username=user_model.username)
        except MobileUserModel.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 CommentList(generics.ListCreateAPIView):
    queryset = CommentModel.objects.all()
    serializer_class = CommentSerializer
    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:
            temp_board_id = request.data["board_id"]
        except KeyError:
            return JsonResponse(json_error("E0002"), status=status.HTTP_400_BAD_REQUEST)

        try:
            ck = access_id(request.headers["AccessToken"])
            if ck is not False:
                user_model = ck
                request.data.update(comment_user_id=user_model.pk)
                request.data.update(comment_username=user_model.username)
                request.data.update(comment_user_type=user_model.user_type)
                request.data.update(comment_nickname=user_model.nickname)
                request.data.update(comment_profile=user_model.profile)
        except MobileUserModel.DoesNotExist:
            return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)

        try:
            board_id = BoardModel.objects.get(id=temp_board_id).id
            request.data.update(board_id=board_id)
        except BoardModel.DoesNotExist:
            return JsonResponse(json_error("E0010"), 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 BoardUpdate(generics.RetrieveUpdateAPIView):
    queryset = BoardModel.objects.all()
    serializer_class = BoardSerializer
    ordering = ['id']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['board_title', 'board_content', 'board_type']
    lookup_field = 'id'

    def get(self, request, *args, **kwargs):
        pass

    def put(self, request, *args, **kwargs):
        if validation(request.headers):
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)

            if getattr(instance, '_prefetched_objects_cache', None):
                instance._prefetched_objects_cache = {}

            return JsonResponse(json_success("S0002", serializer.data), status=status.HTTP_200_OK)
        else:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)


class CommentUpdate(generics.RetrieveUpdateAPIView):
    queryset = CommentModel.objects.all()
    serializer_class = CommentSerializer
    ordering = ['id']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['comment_title', 'comment_content', 'comment_username']
    lookup_field = 'id'

    def get(self, request, *args, **kwargs):
        pass

    def put(self, request, *args, **kwargs):
        if validation(request.headers):
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)

            if getattr(instance, '_prefetched_objects_cache', None):
                instance._prefetched_objects_cache = {}

            return JsonResponse(json_success("S0002", serializer.data), status=status.HTTP_200_OK)
        else:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)


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

    if request.method == "POST":
        print(request.body)
        data = JSONParser().parse(request)
        try:
            temp_board_id = data["board_id"]
        except KeyError:
            return JsonResponse(json_error("E0002"), status=status.HTTP_400_BAD_REQUEST)

        try:
            ck = access_id(request.headers["AccessToken"])
            if ck is not False:
                try:
                    board_model = BoardModel.objects.get(id=temp_board_id)
                    content = {"id": board_model.id, "board_title": board_model.board_title}
                    board_model.delete()
                    return JsonResponse(json_success("S0003", content), status=status.HTTP_200_OK)
                except BoardModel.DoesNotExist:
                    return JsonResponse(json_error("E0010"), status=status.HTTP_400_BAD_REQUEST)
            else:
                return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except MobileUserModel.DoesNotExist or KeyError:
            return JsonResponse(json_error("E0400"), status=status.HTTP_400_BAD_REQUEST)


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

    if request.method == "POST":
        print(request.body)
        data = JSONParser().parse(request)
        try:
            temp_comment_id = data["comment_id"]
        except KeyError:
            return JsonResponse(json_error("E0002"), status=status.HTTP_400_BAD_REQUEST)

        try:
            ck = access_id(request.headers["AccessToken"])
            if ck is not False:
                try:
                    comment_model = CommentModel.objects.get(id=temp_comment_id)
                    content = {"id": comment_model.id, "comment_title": comment_model.comment_title}
                    comment_model.delete()
                    return JsonResponse(json_success("S0003", content), status=status.HTTP_200_OK)
                except CommentModel.DoesNotExist:
                    return JsonResponse(json_error("E0010"), status=status.HTTP_400_BAD_REQUEST)
            else:
                return JsonResponse(json_error("E0013"), status=status.HTTP_400_BAD_REQUEST)
        except MobileUserModel.DoesNotExist or KeyError:
            return JsonResponse(json_error("E0400"), status=status.HTTP_400_BAD_REQUEST)


@csrf_exempt
def user_board_count(request):
    if request.method == "GET":
        try:
            if request.headers["PrivatKey"] != "Kwonputer":
                return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

        except KeyError:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

        try:
            temp_request_access_token = request.headers["AccessToken"]
            ck = access_id(temp_request_access_token)
            if ck is False:
                return JsonResponse(json_error("E0011"), status=status.HTTP_400_BAD_REQUEST)
        except KeyError:
            return JsonResponse(json_error("E0007"), status=status.HTTP_400_BAD_REQUEST)

        try:
            board_model = BoardModel.objects.filter(board_user_id=ck)
            board_model_count = board_model.count()
            return JsonResponse(json_success("S0004", {"board_total_count": board_model_count}), status=status.HTTP_200_OK)

        except KeyError:
            return JsonResponse(json_error("E0002"), status=status.HTTP_400_BAD_REQUEST)
        except BoardModel.DoesNotExist:
            return JsonResponse(json_error("E0010"), status=status.HTTP_400_BAD_REQUEST)
    else:
        return JsonResponse(json_error("E0006"), status=status.HTTP_400_BAD_REQUEST)

 

오늘은 게시판(board)부분을 개발해놨다.

저번에 글에 작성했던 내용을 토대로 개발했다.

한가지 테스트해봐야하는건, 좋아요 기능인데..

일단 생각해둔 방법은 있다.

외래키로 게시판 글이랑 댓글을 가지는 좋아요 모델을 만들어서,

좋아요 버튼을 누르면 특정 api로 통신을 보내서, 각 모델에 맞는 값을 생성하고, 그 개수에 따라 글과 댓글의 좋아요 카운트를 계산하는 식으로 해보려고 한다.

실제로 해본 적 없는 기능인데.. 위에 생각한대로 개발하면 될 것 같다.

 

내일은 토큰이랑 비밀번호 암호화 등등 만들어놔야겠다.

토큰은 접근 토큰, 갱신 토큰을 둘 다 만들까 했지만, 번거로우니까 그냥 토큰 하나로만 통신하려고한다.

진짜 각잡고 상용화앱을 만드는게 아니니까.. 그래도 기업에서 하는 방식들은 최대한 사용해보려고한다.