티스토리 뷰
AI웹 개발자 과정 공부 (팀스파르타)/Django (장고)
24.05.04_TIL (Django 심화 : Class Based View, Relationship과 DRF )
티아(tia) 2024. 5. 30. 16:48반응형
++ 장고 공식 문서는 항상 확인하기
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)
- 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": "댓글수정"
}
반응형
'AI웹 개발자 과정 공부 (팀스파르타) > Django (장고)' 카테고리의 다른 글
24.05.06_TIL (Django 심화 : account 만들기 회원가입 JWT ) (0) | 2024.05.30 |
---|---|
24.05.05_TIL (Django 심화 : Serializer 활용 ) (0) | 2024.05.30 |
24.05.03_TIL (Django 심화 : Single Model CRUD) (0) | 2024.05.30 |
24.05.01_TIL (Django 심화 : Json Response) (0) | 2024.05.30 |
24.05.02_TIL (Django 심화 : REST Framework 시작하기) (0) | 2024.05.02 |