내가 쓴 글이 있으면 밑에 댓글 기능을 추가 하고싶은 요구사항이 생기는 것은 당연하다. Comment 자체를 새로운 App 으로 만들어서 구현한 예제도 있는 듯 하나 Post 모델과 Comment 모델을 하나의 app 에서 정의해보는 예제를 구현해 보았다.
1. Comment 모델 추가
기존에 사용하던 app 의 post 모델이 선언된 models.py 파일에 아래와 같이 Comment Model을 추가해준다.
text field 하나를 가지고, post field 는 foreignkey 로 선언해준다. foreignkey 에 Post 모델을 넣어주면 comment 는 Post 에 종속성을 가진다.
models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
image = models.ImageField(upload_to="%Y/%m/%d")
class Comment(models.Model):
text = models.CharField(max_length=200)
post = models.ForeignKey('Post', related_name='comments', on_delete=models.CASCADE, blank=True)
2. Serializers 추가
Comment 모델에 대한 직렬화를 해주기 위하여 생성해 놓은 serializers.py 파일에 CommentSerializer 를 정의 해준다.
.model 에 Comment 를 import 시켜주는 것은 잊지말자. CommentSerializer 의 model 에 Comment 를 정의해주고 fields 에는 __all__을 넣어주면 Comment 모델에서 사용하는 모든 field 가 들어간다.
기존에 PostSerializer 에는 comments field 를 추가해 주는데 하나의 Post에는 여러개의 comment 가 존재할 수 있으므로 many=True 라고 정의 해준다.
Serializers.py
from rest_framework import serializers
from .models import Post, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
class PostSerializer(serializers.ModelSerializer):
image = serializers.ImageField(use_url=True)
comments = CommentSerializer(many=True, read_only=True)
class Meta:
model = Post
fields = ('title', 'text', 'image', 'comments')
3. Viewset 추가
View는 가장 쉬운 Viewset 을 사용하여 Comment 의 View 를 정의해보았다.
여기에서도 새로만든 Comment 모델과 CommentSerializer 를 import 하는 것을 잊지 말자.
기존에 선언해 두었던 Postviewset 과 동일하게 CommentViewset 를 정의해줫다.
views.py
from rest_framework import viewsets
from .serializers import PostSerializer, CommentSerializer
from .models import Post, Comment
class PostViewset(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
class CommentViewset(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
4. URL 추가
url은 기존에 post 가 쓰고 있었던 Router에 CommentViewset 을 추가 해주기만 하면 바로 동작된다.
알고 있겟지만 viewset 을 사용하면 자동으로 CRUD 에 해당하는 URL 이 정의 된다.
아래에서 추가되는 코드는 router.register(r'comments', views.CommentViewset) 이 것 단 한줄이다.
urls.py
router = routers.DefaultRouter()
router.register(r'posts', views.PostViewset)
router.register(r'comments', views.CommentViewset)
urlpatterns = [
url(r'^',include(router.urls)),
...
5. 실행
실행해보자 실행전에 database migration을 진행한다. 진행 후 server를 실행한다.
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
http://localhost:8000/ 에 접속하면 기존에는 posts api 밖에 없었지만 comments 까지 추가가 되 있는 것을 볼 수 있다.
posts 를 호출해보면 Post Model에 추가적으로 정의했던 comments field 가 추가된 것을 확인 할 수 있다. 원래는 공백이지만 나는 미리 구현 해놓고 테스트를 해봐서 comment 들이 남아 있는 상황이다.
이제 http://localhost:8000/comments/ 에 들어가보자. 내가 입력했던 comment들을 볼 수 있고 아래의 입력창을 보게 되면 text 와 Post field 가 있다.
Post field 의 경우 Foreign key 로 선언을 해놓았기 때문에 작성한 Post 들 중에서 선택할 수 있는 UI 를 만날 수 있다.
하나 선택을 해서 입력을 해보자. Post를 누르게 되면 아래와 같이 입력한 comment 가 저장이 되고 post field 에는 post의 PK 값이 들어가게 된다.
Comment 가 잘내려오는지 Post 에 가서 확인해보자. 아래와 같이 내가 선택했던 Post에 댓글이 성공적으로 추가된 것을 확인 할 수 있다.
Post Field 에 내가 선언해 놓은 field 들이 더 있어서 보이는 것이니 혼동하지 말자.
'Django' 카테고리의 다른 글
[Django] RestFramework Pagination 예제 (0) | 2019.10.10 |
---|---|
[Django] RestFramework Image file upload ImageField (0) | 2019.10.04 |
[Django] Django-rest-auth 회원가입, 로그인, 로그아웃 예제 (0) | 2019.09.28 |
Django ngrok 설정, 홈 서버 (0) | 2019.09.22 |
Django REST framework 예제 (1) | 2019.09.21 |