내가 쓴 글이 있으면 밑에 댓글 기능을 추가 하고싶은 요구사항이 생기는 것은 당연하다. 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 들이 더 있어서 보이는 것이니 혼동하지 말자. 

 

+ Recent posts