from django.db import models
from users.models import User
class Article(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) # 삭제할 때 없애준다
title = models.CharField(max_length=50)
content = models.TextField()
image = models.ImageField(blank=True, upload_to='%Y/%m/')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.title)
# 댓글. 필요한 필드를 생각해보기. class를 def 위치에 쓰지 않도록 주의
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE) # 게시글 삭제시 댓글도 삭제됨
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# string method를 추가한다.
def __str__(self):
return str(self.content)
model을 만들었으니 makemigrations, migrate
만든 model을 테스트해보려면 admin에서 테스트해본다.
admin에 등록하기
# articles/admin.py
from django.contrib import admin
from articles.models import Article, Comment # 추가
admin.site.register(Article)
admin.site.register(Comment) # 추가
# articles/urls.py
from django.urls import path
from articles import views
urlpatterns = [
path('', views.ArticleView.as_view(), name='article_view'),
path('<int:article_id>/', views.ArticleDetailView.as_view(), name='article_detail_view'),
path('<int:article_id>/comment/', views.CommentView.as_view(), name='comment_view'),
path('<int:article_id>/comment/<int:comment_id>', views.CommentDetailView.as_view(), name='comment_detail_view'),
path('<int:article_id>/like/', views.LikeView.as_view(), name='like_view'),
]
# articles/serializers.py
from rest_framework import serializers
from articles.models import Article, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
class CommentCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ("content",)
# fields 안에 1개만 쓸 때 ,를 꼭 붙여야 한다. 안 쓰면 str로 인식
# articles/views.py
from rest_framework.generics import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status, permissions
from rest_framework.response import Response
from articles.models import Article, Comment # 추가
from articles.serializers import ArticleSerializer, ArticleListSerializer, ArticleCreateSerializer, CommentSerializer, CommentCreateSerializer
class ArticleView(APIView):
def get(self, request):
articles = Article.objects.all() # 모두
serializer = ArticleListSerializer(articles, many=True) # 복수
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
# 먼저 serializer를 불러온다. () 안에 데이터를 저장한다.
serializer = ArticleCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user)
return Response(serializer.data)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# id가 있어야 쓰는 API. 인자가 1개 더 있다.
class ArticleDetailView(APIView):
def get(self, request, article_id):
# article = Article.objects.get(id=article_id) 아래가 더 효율적인 코드
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
# 수정
def put(self, request, article_id):
article = get_object_or_404(Article, id=article_id)
if request.user == article.user:
serializer = ArticleCreateSerializer(article, data=request.data)
if serializer.is_valid():
serializer.save() # article에 user 정보 있기 때문에 (user=request.user) 생략
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)
# 삭제
def delete(self, request, article_id):
article = get_object_or_404(Article, id=article_id)
if request.user == article.user:
article.delete()
return Response("삭제되었습니다.", status=status.HTTP_204_NO_CONTENT)
else:
return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)
class CommentView(APIView):
# 해당 게시글의 댓글을 불러오기. 댓글은 상세페이지 없고 댓글 리스트, 수정, 삭제 있다.
def get(self, request, article_id):
article = Article.objects.get(id=article_id)
comments = article.comment_set.all() # article에 대해 작성된 comment와 쿼리셋을 불러온다.
serializer = CommentSerializer(comments, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request, article_id):
serializer = CommentCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user, article_id=article_id) # article=Article.objects.get(id=article_id)
return Response(serializer.data, status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CommentDetailView(APIView):
def put(self, request, article_id, comment_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
serializer = CommentCreateSerializer(comment, data=request.data)
if serializer.is_valid():
serializer.save() # article에 user 정보 있기 때문에 (user=request.user) 생략
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)
def delete(self, request, article_id, comment_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
comment.delete()
return Response("삭제되었습니다.", status=status.HTTP_204_NO_CONTENT)
else:
return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)
class LikeView(APIView):
def post(self, request, article_id):
pass