티스토리 뷰

728x90

 

 

 

++ 장고 공식 문서는 항상 확인하기 

https://docs.djangoproject.com/en/4.2/

 

++ 과제 API 를 정해주어서 수정하여 진행

필수 기능 - MVP(Minimum Viable Product)

  • 상품 등록
    • Endpoint: /api/products
    • Method: POST
    • 조건: 로그인 상태, 제목과 내용, 상품 이미지 입력 필요.
    • 구현: 새 게시글 생성 및 데이터베이스 저장.
  • 상품 목록 조회
    • Endpoint: /api/products
    • Method: GET
    • 조건: 로그인 상태 불필요.
    • 구현: 모든 상품 목록 페이지네이션으로 반환.
  • 상품 수정
    • Endpoint: /api/products/<int:productId>
    • Method: PUT
    • 조건: 로그인 상태, 수정 권한 있는 사용자(게시글 작성자)만 가능.
    • 검증: 요청자가 게시글의 작성자와 일치하는지 확인.
    • 구현: 입력된 정보로 기존 상품 정보를 업데이트.
  • 상품 삭제
    • Endpoint: /api/products/<int:productId>
    • Method: DELETE
    • 조건: 로그인 상태, 삭제 권한 있는 사용자(게시글 작성자)만 가능.
    • 검증: 요청자가 게시글의 작성자와 일치하는지 확인.
    • 구현: 해당 상품을 데이터베이스에서 삭제.

필수 기능 - MVP(Minimum Viable Product)

  • 회원가입
    • Endpoint: /api/accounts
    • Method: POST
    • 조건: username, 비밀번호, 이메일, 이름, 닉네임, 생일 필수 입력하며 성별, 자기소개 생략 가능
    • 검증: username과 이메일은 유일해야 하며, 이메일 중복 검증(선택 기능).
    • 구현: 데이터 검증 후 저장.
  • 로그인
    • Endpoint: /api/accounts/login
    • Method: POST
    • 조건: 사용자명과 비밀번호 입력 필요.
    • 검증: 사용자명과 비밀번호가 데이터베이스의 기록과 일치해야 함.
    • 구현: 성공적인 로그인 시 토큰을 발급하고, 실패 시 적절한 에러 메시지를 반환.
  • 프로필 조회
    • Endpoint: /api/accounts/<str:username>
    • Method: GET
    • 조건: 로그인 상태 필요.
    • 검증: 로그인 한 사용자만 프로필 조회 가능
    • 구현: 로그인한 사용자의 정보를 JSON 형태로 반환.

 

 

 

 

 

 

 

 

1.  Class Based View 사용하기

  • 📕 Django의 View는 두가지 방식으로 작성할 수 있습니다.
    • 함수형 뷰 (Function Based View, FBV)
    • 클래스형 뷰 (Class Based View, CBV)
    ⇒ DRF 역시 두가지 방식의 View 형태로 작성이 가능합니다!

 

 

 

  • views.py 를 class 로 수정해보자.
from rest_framework.views import APIView

class ArticleListAPIView(APIView):
    def get(self, request):
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
  • urls.py 변경해야함
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("", views.ArticleListAPIView.as_view(), name="article_list"),
    ...
]

 

 

수정하고서도 목록조회가 잘 되는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

  • views.py 를 class 로 수정해보자.
class ArticleDetailAPIView(APIView):

		# 두 번 이상 반복되는 로직은 함수로 빼면 좋습니다👀
    def get_object(self, article_pk):
        return get_object_or_404(Article, pk=article_pk)

    def get(self, request, article_pk):
        article = self.get_object(article_pk)
        serializer = ArticleSerializer(article)
        return Response(serializer.data)

    def put(self, request, article_pk):
        article = self.get_object(article_pk)
        serializer = ArticleSerializer(article, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

    def delete(self, request, article_pk):
        article = self.get_object(article_pk)
        article.delete()
        data = {"pk": f"{article_pk} is deleted."}
        return Response(data, status=status.HTTP_200_OK)

 

 

  • urls.py 변경해야함
path("<int:article_pk>/", views.ArticleDetailAPIView.as_view(), name="article_detail"),

 

 

 

 

 

 

 

 

 

 

 

 

 

2.  댓글 구현을 해보자.

  • API는 과제에서 articles를 products로 바꾸어서 진행한다.

  • articles에서 models.py를 추가하기
class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name="comments")
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

 

  • 마이그레이션을 해주자.
python manage.py makemigrations
python manage.py migrate

 

  • articles에 serializers.py 를 추가하기
from .models import Article, Comment

...

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = "__all__"

 

 

  • django seed로 생성하기
python manage.py seed articles --number=20

comment랑 article이 같이 랜덤하게 20개가 생성된다.

 

 

 

 

 

 

 

 

3.  댓글 조회하기

  • articles에 urls.py 에 추가하기
path(
        "<int:article_pk>/comments/",
        views.CommentListAPIView.as_view(),
        name="comment_list",
    ),

 

  • articles에 views.py 에 추가하기
from .serializers import ArticleSerializer, CommentSerializer

...

class CommentListAPIView(APIView):
    def get(self, request, article_pk):
        article = get_object_or_404(Article, pk=article_pk)
        comments = article.comments.all()
        serializer = CommentSerializer(comments, many=True)
        return Response(serializer.data)

    def post(self, request, article_pk):
        pass

 

 

  • django seed를 특정 article 에 댓글을 20개 생성해보자.
python manage.py seed articles --number=20 --seeder "Comment.article_id" 2

 

2번 게시글의 댓글을 조회해보면 잘 조회되는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

4.  댓글 생성하기

  • articles에 views.py 에 추가하기
class CommentListAPIView(APIView):
    ...
    def post(self, request, article_pk):
        article = get_object_or_404(Article, pk=article_pk)
        serializer = CommentSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save(article=article)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

 

  •  댓글 생성해보기
{
	"content": "댓글댓글"
}

 

 

  • serializer.is_valid 를 통과하지 못합니다.이럴 때는 read_only_fields 를 설정해서 특정 필드를 직렬화 로직에 포함하지 않고 반환 값에만 필드를 포함하도록 할 수 있습니다.
  • → serializer 입장에서는 내가 넘겨받은 데이터에 article 정보가 없기 때문입니다!
  • CommentSerializer 에 read_only_fields = ("article",) 를 추가해야한다.
class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = "__all__"
        read_only_fields = ("article",)

 

++ Body 에서 raw 선택후 Json 선택해서 작성

 

 

 

 

 

 

 

 

 

 

 

 

 

5.  댓글 삭제하기

  • articles에 urls.py 에 추가하기
path(
    "comments/<int:comment_pk>/",
    views.CommentDetailAPIView.as_view(),
    name="comment_detail",
),

 

 

  • articles에 views.py 에 추가하기
from .models import Article , Comment

class CommentDetailAPIView(APIView):
    def delete(self, request, comment_pk):
        comment = get_object_or_404(Comment, pk=comment_pk)
        comment.delete()
        data = {"pk": f"{comment_pk} is deleted."}
        return Response(data, status=status.HTTP_200_OK)

같은 코드임

class CommentDetailAPIView(APIView):
    def delete(self, request, comment_pk):
        comment = get_object_or_404(Comment, pk=comment_pk)
        comment.delete()
        data = {"pk": f"{comment_pk} is deleted."}
        return Response(data, status=status.HTTP_200_OK)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6.  댓글 수정하기

 

  • articles에 views.py 에 추가하기
class CommentDetailAPIView(APIView):
    def get_object(self, comment_pk):
        return get_object_or_404(Comment, pk=comment_pk)

    def put(self, request, comment_pk):
        comment = self.get_object(comment_pk)
        serializer = CommentSerializer(comment, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

위와 같음

class CommentDetailAPIView(APIView):
    def put(self, request, comment_pk):
        comment = get_object_or_404(Comment, pk=comment_pk)
        serializer = CommentSerializer(comment, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

 

 

{
	"content": "댓글수정"
}

 

 

 

 

 

 

 

 

 

 

 

반응형
반응형
TAG
more
최근에 올라온 글