class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Comment(models.Model) :
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)
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py seed articles --number=20
class CommentSerializer(serializers.ModelSerializer) :
class Meta :
model = Comment
fields = '__all__'
#urls.py
urlpatterns = [
path('comments/',views.comment_list),
]
#views.py
@api_view(['GET'])
def comment_list(request) :
comments = get_list_or_404(Comment)
serializer = CommentSerializer(comments,many=True)
return Response(serializer.data)
#urls.py
urlpatterns = [
path('comments/<int:comment_pk>/', views.comment_detail),
]
#views.py
@api_view(['GET'])
def comment_detail(request, comment_pk) :
comment = get_object_or_404(Comment, pk=comment_pk)
serializer = CommentSerializer(comment)
return Response(serializer.data)
#urls.py
urlpatterns = [
path('articles/<int:article_pk>/comments/', views.comment_create),
]
#views.py
@api_view(['POST'])
def comment_create(request,article_pk) :
serializer = CommentSerializer(data=request.data)
if serializer.is_valid(raise_exception=True) :
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
요청 보낸 결과 400에러 발생
응답 : {"article":["This field is required."]}
몇 번 게시글에 작성할지에 대한 명시가 없기 때문
@api_view(['POST'])
def comment_create(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)
어떤 게시글에 작성하는 댓글인지에 대한 정보를 form-data로 넘겨주지 않았기 때문에 직렬화하는 과정에서 article 필드가 유효성 검사(is_valid)를 통과하지 못함
이때는 읽기 전용 필드 설정을 통해 직렬화하지 않고 반환값에만 해당 필드가 포함되도록 설정할 수 있음
class CommentSerializer(serializers.ModelSerializer) :
class Meta :
model = Comment
fields = '__all__'
read_only_fields = ('article',)
@api_view(['GET','PUT','DELETE'])
def comment_detail(request, comment_pk) :
comment = get_object_or_404(Comment, pk=comment_pk)
if request.method=='GET' :
serializer = CommentSerializer(comment)
return Response(serializer.data)
elif request.method=='DELETE' :
comment.delete()
data = {
#pk는 url에서 가져온 article_pk이다.
'delete' : f'데이터 {comment_pk}번이 삭제 되었습니다.'
}
return Response(data, status=status.HTTP_204_NO_CONTENT)
elif request.method=='PUT' :
serializer = CommentSerializer(comment,data=request.data)
if serializer.is_valid(raise_exception=True) :
serializer.save()
return Response(serializer.data)
class ArticleSerializer(serializers.ModelSerializer) :
comment_set = serializers.PrimaryKeyRelatedField(many=True,read_only = True)
class Meta:
model = Article
fields = '__all__'
class Comment(models.Model) :
article = models.ForeignKey(Article,on_delete=models.CASCADE, related_name='comments')
class CommentSerializer(serializers.ModelSerializer) :
class Meta :
model = Comment
fields = '__all__'
read_only_fields = ('article',)
class ArticleSerializer(serializers.ModelSerializer) :
comment_set = CommentSerializer(many=True,read_only=True)
class Meta:
model = Article
fields = '__all__'
class ArticleSerializer(serializers.ModelSerializer) :
comment_set = CommentSerializer(many=True,read_only = True)
comment_count = serializers.IntegerField(source='comment_set.count', read_only=True)
class Meta:
model = Article
fields = '__all__'
class ArticleSerializer(serializers.ModelSerializer) :
comment_set = serializers.PrimaryKeyRelatedField(many=True)
comment_count = serializers.IntegerField(source='comment_set.count')
class Meta:
model = Article
fields = '__all__'
read_only_fields = ('comment_set','comment_count')