본문 바로가기
부트캠프TIL, WIL/AI웹개발(스파르타코딩클럽)

[AI웹개발][62일차TIL] 쇼핑몰 상품게시글 CRUD, 상품 문의 CRUD, 문의 댓글 CRUD

by 우지uz 2023. 6. 13.

AI 웹개발 - 62일차 TIL : 상품 관련 백엔드 API 기능 구현 (CRUD)6월 13일 화요일

목차
1. 상품 게시글 CRUD
2. 상품 문의 CRUD
3. 문의 댓글 CRUD
4. 상품 후기 모델, CRUD를 삭제한 이유
5. 느낀 점

1. 상품 게시글 CRUD

views.py 

# 23년 6월 12일
# 상품문의모델 : Product
# 시리얼라이저 : ProductListSerializer, ProductCreateSerializer, ProductDetailSerializer
class ProductView(APIView):
    def get(self, request):
        products = Product.objects.all().order_by("-created_at")
        serializer = ProductListSerializer(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 로그인 된 사용자에 대해서 상품 게시글 작성 가능
    def post(self, request):
        serializer = ProductCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ProductDetailView(APIView):
    def get(self, request, product_id):
        product = get_object_or_404(Product, id=product_id)
        serializer = ProductDetailSerializer(product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    
    def put(self, request, product_id):
        product = get_object_or_404(Product, id=product_id)
        if request.user == product.user:
            serializer = ProductCreateSerializer(
                product, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'message':'권한이 없습니다.'}, status.HTTP_403_FORBIDDEN)


    def delete(self, request, product_id):
        product = get_object_or_404(Product, id=product_id)
        if request.user == product.user:
            product.delete()
            return Response({"message": "삭제완료!"}, status=status.HTTP_204_NO_CONTENT)
        else:
            return Response({'message':'권한이 없습니다.'}, status=status.HTTP_403_FORBIDDEN)

serializers.py

# 23년 6월 12일
# 상품 리스트
class ProductListSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    def get_user(self, obj):
        return {"nickname": obj.user.username, "id": obj.user.id, "product_img": str(obj.user.product_img)}

    class Meta:
        model = Product
        fields = ["id", "product_name", "product_price", "product_stuck", "product_explane", "product_img", "user", "hearts"]

# 23년 6월 12일
# 상품 게시글 작성
class ProductCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = [
            "product_name", "product_price", "product_stuck", "product_explane", "product_img"
            ]
        extra_kwargs={
            "product_name": {
                "error_messages": {
                    "blank": "상품 이름을 입력해주세요",
                }
            },
            "product_price": {
                "error_messages": {
                    "blank": "상품 가격을 입력해주세요",
                },
            },
            "product_stuck": {
                "error_messages": {
                    "blank": "재고 수량을 입력해주세요",
                },
            },
            "product_explane": {
                "error_messages": {
                    "blank": "상품 설명을 입력해주세요",
                },
            },
            "product_img": {
                "error_messages": {
                    "blank": "상품 사진을 입력해주세요",
                },
            },
        }


# 23년 6월 12일
# 상품 상세보기 시리얼라이저
class ProductDetailSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    product_inquery = InqueryListserializer(many=True)
    like_count = serializers.SerializerMethodField()

    def get_user(self, obj):
        return {"username": obj.user.username, "id": obj.user.id}

    def get_like_count(self, obj):
        return obj.like_count.count()

    class Meta:
        model = Product
        fields = "__all__"

2. 상품 문의 CRUD

views.py 

# 23년 6월 13일, 아직 수정 안함
# 상품문의모델 : ProductInquery
# 시리얼라이저 : InqueryCreateSerializer, InqueryListserializer
class ProductInqueryView(APIView):

    def get(self, request):
        inqueries = ProductInquery.objects.all().order_by("-created_at")
        serializer = InqueryListserializer(inqueries, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    
    def post(self, request):
        serializer = InqueryCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ProductInqueryDetailView(APIView):

    def put(self, request, inquery_id):
        inquery = get_object_or_404(ProductInquery, id=inquery_id)
        if request.user == inquery.user:
            serializer = ProductCreateSerializer(
                inquery, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'message':'권한이 없습니다.'}, status.HTTP_403_FORBIDDEN)

    def delete(self, request, inquery_id):
        inquery = get_object_or_404(ProductInquery, id=inquery_id)
        if request.user == inquery.user:
            inquery.delete()
            return Response({"message": "삭제완료!"}, status=status.HTTP_204_NO_CONTENT)
        else:
            return Response({'message':'권한이 없습니다.'}, status=status.HTTP_403_FORBIDDEN)

serializers.py

# ============== 상품 문의 시작 ================
# 23년 6월 12일
# 상품 문의 생성 시리얼라이저
class InqueryCreateSerializer(serializers.ModelSerializer):
    product = serializers.SerializerMethodField()
    user = serializers.SerializerMethodField()

    def get_product(self, obj):
        return {"product_name": obj.product.product_name, "id": obj.product.id}

    def get_user(self, obj):
        return {"username": obj.user.username, "id": obj.user.id}

    class Meta:
        model = ProductInquery
        fields = [
            "product", "product_name", "inquery_title", "inquery_content"
            ]
        extra_kwargs={
            "inquery_title": {
                "error_messages": {
                    "blank": "상품 이름을 입력해주세요",
                }
            },
            "inquery_content": {
                "error_messages": {
                    "blank": "상품 가격을 입력해주세요",
                },
            },
        }

# 23년 6월 12일
# 상품 문의 모아보기 시리얼라이저
class InqueryListserializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    def get_user(self, obj):
        return {"username": obj.user.username, "id": obj.user.id}

    class Meta:
        model = ProductInquery
        fields = ["inquery_title", "inquery_content", "is_complete"]

# ============== 상품 문의 끝 ================

3. 문의 댓글 CRUD

views.py 

# 23년 6월 12일 작성
# 23년 6월 13일, 오후 1시38분 강의 후 수정 및 체크 완료
# 상품문의댓글모델 : ProductInqueryComment
# 시리얼라이저 : CommentListserializer, CommentCreateSerializer
class CommentView(APIView):
    # 관리자만 댓글 가능 - 상품 리뷰, 상품 문의에 대한 답변기능

    def get(self, request, product_id):
        product = get_object_or_404(Product, id=product_id)
        comments = product.comments.all().order_by("-created_at")
        serializer = CommentListserializer(comments, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request, product_id):
        product = get_object_or_404(Product, id=product_id)
        serializer = CommentCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(product=product, user=request.user)
            return Response(({"message": "댓글 작성 완료!"}, serializer.data), status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CommentDetailView(APIView):
    # 관리자만 댓글 수정/삭제 가능 - 상품 리뷰, 상품 문의에 대한 답변기능
    permission_classes = [permissions.IsAdminUser]
    # 댓글 수정하기
    def put(self, request, comment_id):
        comment = get_object_or_404(ProductInqueryComment, id=comment_id)
        serializer = CommentCreateSerializer(comment, data=request.data)
        if comment.user == request.user:
            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(({"message": "댓글 수정 완료!"}, serializer.data), status=status.HTTP_200_OK)
        else:
            return Response({"message": "나의 댓글만 수정할 수 있습니다."}, status=status.HTTP_401_UNAUTHORIZED)

    # 댓글 삭제하기
    def delete(self, request, comment_id):
        comment = get_object_or_404(ProductInqueryComment, id=comment_id)
        if comment.user == request.user:
            comment.delete()
            return Response({"message": "댓글 삭제 완료!"}, status=status.HTTP_204_NO_CONTENT)
        else:
            return Response({"message": "나의 게시물만 삭제할 수 있습니다."}, status=status.HTTP_401_UNAUTHORIZED)

serializers.py

# ============== 관리자 답변 시리얼라이저 시작 ================
# 23년 6월 12일
# 관리자 댓글 생성 시리얼라이저
class CommentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductInqueryComment
        fields = [
            "inquery_title", "inquery_content"
            ]
        extra_kwargs={
            "inquery_title": {
                "error_messages": {
                    "blank": "상품 이름을 입력해주세요",
                }
            },
            "inquery_content": {
                "error_messages": {
                    "blank": "상품 가격을 입력해주세요",
                },
            },
        }

# 23년 6월 12일
# 관리자 댓글 보기 시리얼라이저
class CommentListserializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    def get_user(self, obj):
        return {"username": obj.user.username, "id": obj.user.id}

    class Meta:
        model = ProductInqueryComment
        fields = ["id", "inquery_title", "inquery_content"]

# ============== 관리자 답변 시리얼라이저 끝 ================

4. 상품 후기 모델, CRUD를 삭제한 이유

상품 후기 모델을 상품 앱에 작성하려고 하니, 
상품 후기 같은 경우는 상품을 결제한 사용자에 대해서만 작성할 수 있어야 하기 때문에
결제 앱에서 따로 결제 모델, 상품후기 모델 및 장바구니 모델을 만든 다음에
상품 후기 게시글을 작성할 수 있도록 하는게 좋다고 판단하여 삭제했습니다. 
상품 결제 앱에서 기능 구현할 예정입니다. 


5. 느낀점

앱에 따라, 기능을 어떻게 나눌 것인지에 대해 
다시 한번 생각해보게 되는 계기 였습니다. 
DRF  및 Serializer 를 많이 사용해보게 되는 시간 이었습니다. 
쇼핑몰 ERD 및 모델링이 이렇게 어려운 거구나.. 라는 것을 매일 느끼고 있는데 
공부를 진득 ~ 하니 한다는 느낌으로 
꾸준하게 , 끝까지 완성시키고 
배포까지 성공해서 
블로그에 올려보도록 하겠습니다. 
 
AI웹개발 최종 S.A 노션 링크
AI웹개발 강의 자료 정리