AI웹 개발자 과정 공부 (팀스파르타)/Django (장고)

24.05.03_TIL (Django 심화 : Single Model CRUD)

티아(tia) 2024. 5. 30. 16:48
728x90

 

 

 

 

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

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

 

 

 

1.  Single Model CRUD 를 사용하기 위해 코드 정리하기

  • articles 에서의 views.py 와 urls.py 를 정리해준다.
  • templates는 안쓰니까 삭제해주어도 된다.

  • 위의 사진처럼 API 설계를 해준다.

++ 과제 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 형태로 반환.

 

 

 

 

 

 

 

 

2.  상품 목록조회 만들기

  • articles의 urls.py 에 만들어준다.
from django.urls import path
from . import views

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

 

 

  • articles에 views.py를 만들어준다.
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ArticleSerializer
from .models import Article


@api_view(["GET"])
def article_list(request):
    articles = Article.objects.all()
    serializer = ArticleSerializer(articles, many=True)
    return Response(serializer.data)

 

  • api_pjt 에서 urls.py 에서  수정
path('api/products/', include('articles.urls')),

 

  • Postman 에 추가하기

 

 

 

 

 

 

 

 

 

 

 

 

3.  상품 상세 조회 만들기

  • articles의 urls.py 에 만들어준다.
path("<int:pk>/", views.article_detail, name="article_detail"),
  • articles에 views.py를 만들어준다.
from django.shortcuts import render, get_object_or_404

...

@api_view(["GET"])
def article_detail(request, pk):
    article = get_object_or_404(Article, pk=pk)
    serializer = ArticleSerializer(article)
    return Response(serializer.data)

 

  • Postman 에 추가하기

 

목록에 없는 게시글을 조회하면 404 에러가 뜬다.

 

 

 

 

 

 

 

 

 

 

 

 

4.  상품 생성 하기 

  • articles의 urls.py 에 이미 생성되어 있다. list를 get으로 하면 조회지만 post로 받으면 만들수 있음!
from django.urls import path
from . import views

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

 

 

  • articles에 views.py에서 수정해준다.
@api_view(["GET", "POST"])
def article_list(request):
    if request.method == "GET":
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
    elif request.method == "POST":
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201) # status 안써도됨(회사약속)
        return Response(serializer.errors, status=400)

 

 

 

 

 

 

 

  • 여기서 코드를 좀 더 생략할 수 있다.
from rest_framework import status

...

@api_view(["GET", "POST"])
def article_list(request):
    if request.method == "GET":
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
    elif request.method == "POST":
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED) # 201을 명시해줌

 

  • raise_exception=True
    • is_valid 하지 않을시 serializers.ValidationError를 발생시키는 옵션입니다.
    • DRF 내부의 예외처리 로직에 의해 처리되어 400 응답을 반환합니다.

 

 

 

 

 

 

 

 

 

5.  상품 삭제 하기 

  • articles의 urls.py 에 이미 생성되어 있다. detail을 delete으로 바꾸면 삭제 가능
  • articles에 views.py에서 수정해준다.
@api_view(["GET", "DELETE"])
def article_detail(request, article_pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "GET":
        serializer = ArticleSerializer(article)
        return Response(serializer.data)

    elif request.method == "DELETE":
        article.delete()
        data = {"delete": f"Article({article_pk}) is deleted."}
        return Response(data, status=status.HTTP_200_OK)

 

 

 

지웠던 글을 다시 지우려고 하면 404 에러가 뜬다. 목록조회나 상세조회에서도 안보이는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

6.  상품 수정 하기 

  • articles의 urls.py 에 이미 생성되어 있다. detail을 put 으로 바꾸면 수정 가능
  • articles에 views.py에서 수정해준다.
@api_view(["GET","PUT", "DELETE"])
def article_detail(request, article_pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "GET":
        serializer = ArticleSerializer(article)
        return Response(serializer.data)
        
    elif request.method == "PUT":
    	serializer = ArticleSerializer(article, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
        	serializer.save()
            return Response(serializer.data)

    elif request.method == "DELETE":
        article.delete()
        data = {"delete": f"Article({article_pk}) is deleted."}
        return Response(data, status=status.HTTP_200_OK)

 

  •  부분 수정을 해야할 때 partial=True 옵션을 주어야한다. 안그러면 하나만 수정했을 때 에러가 난다.
{
	"title": "제목수정",
	"content": "내용수정"
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형