(1) 모델 수정
class Answer(models.Model):
# 질문 - Answer가 Question에 연결
question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='질문', related_name='answers')
# 답변 내용
content = models.TextField(verbose_name='내용')
# 작성자
author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='작성자',related_name='answers')
# 생성 시간
created_at = models.DateTimeField(default=timezone.now,verbose_name='생성 시간')
modified_at = models.DateTimeField(null=True, blank=True)
class Meta:
verbose_name = '답변'
verbose_name_plural = '답변'
def __str__(self):
return f"{self.author}'s answer to {self.question.title}"
질문, 내용, 작성자, 글 생성 시간, 글 수정시간
(2) 답변 조회
localhost:8000/qna/questions/<질문 번호>/answers --> GET
질문 번호에 해당하는 답변들을 가져온다.
class AnswerViewSet(viewsets.ModelViewSet):
queryset = Answer.objects.all()
serializer_class = AnswerSerializer
위와 같이 GET요청시 해당 질문에 해당하는 답변들을 불러온다.
(3) 답변 생성
localhost:8000/qna/questions/<질문 번호>/answers --> POST
"content" 와 "student_id" 즉, 내용과 학번을 POST시 답변이 생성된다.
def create(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾습니다.
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 question_id를 사용하여 해당 질문을 찾기
question_id = kwargs.get('question_id')
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
return Response({"error": "Question not found."},
status=status.HTTP_404_NOT_FOUND)
# 새 Answer 객체를 생성하고 User와 Question 객체를 연결합니다.
answer = Answer(content=data.get('content'), author=user, question=question)
# Answer 객체를 저장합니다.
answer.save()
# 저장된 Answer 객체의 정보를 반환합니다.
return Response({"message": "Answer created successfully", "answer": {
"content": answer.content,
"student_id": user.student_id,
"created_at": answer.created_at,
}}, status=status.HTTP_201_CREATED)
답변이 생성되었다고 뜬다.
제대로 됐는지 확인하기 위해, 다시 답변 조회를 해보면
정상적으로 생성되었다.
(4) 답변 수정
localhost:8000/qna/questions/<질문 번호>/answers/<답변번호> --> PUT
"content" 와 "student_id" 즉, 내용과 학번을 PUT시 답변이 수정된다.
def update(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾습니다.
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
# 권한이 있는 경우 답변 내용 업데이트
answer.content = data.get('content')
answer.modified_at = timezone.now() # Update modified_at field
answer.save()
return Response({"message": "Answer updated successfully"}, status=status.HTTP_200_OK)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to update this answer."},
status=status.HTTP_403_FORBIDDEN)
이렇게 PUT을 하면
수정에 성공했다는 메세지가 뜨고, 제대로 수정됐는지 조회해보면
수정날짜와 함께 잘 수정되었다.
(5) 답변 삭제
localhost:8000/qna/questions/<질문 번호>/answers/<답변번호> --> DELETE
student_id" 즉, 학번을 DELETE시 답변이 삭제된다.
def destroy(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾기
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
answer.delete() # 조건이 충족되면 답변을 삭제
return Response({"message": "Answer deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to delete this answer."},
status=status.HTTP_403_FORBIDDEN)
위와같이 하면, 답변 삭제되었다는 메시지가 나온다.
조회하면
34번 답변이 삭제된 것을 확인할 수 있다.
(6) 답변 상세조회
localhost:8000/qna/questions/<질문 번호>/answers/<답변번호> --> GET.
이 기능은 답변 수정할 때, 기존에 있던 내용을 불러오기 위해서 프론트쪽에서 요청해야할 것이다.
def retrieve(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾기
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
serializer = AnswerSerializer(answer)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to retrieve this answer."},
status=status.HTTP_403_FORBIDDEN)
전체 코드
class AnswerViewSet(viewsets.ModelViewSet):
queryset = Answer.objects.all()
serializer_class = AnswerSerializer
def create(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾습니다.
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 question_id를 사용하여 해당 질문을 찾기
question_id = kwargs.get('question_id')
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
return Response({"error": "Question not found."},
status=status.HTTP_404_NOT_FOUND)
# 새 Answer 객체를 생성하고 User와 Question 객체를 연결합니다.
answer = Answer(content=data.get('content'), author=user, question=question)
# Answer 객체를 저장합니다.
answer.save()
# 저장된 Answer 객체의 정보를 반환합니다.
return Response({"message": "Answer created successfully", "answer": {
"content": answer.content,
"student_id": user.student_id,
"created_at": answer.created_at,
}}, status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾기
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
answer.delete() # 조건이 충족되면 답변을 삭제
return Response({"message": "Answer deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to delete this answer."},
status=status.HTTP_403_FORBIDDEN)
def update(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾습니다.
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
# 권한이 있는 경우 답변 내용 업데이트
answer.content = data.get('content')
answer.modified_at = timezone.now() # Update modified_at field
answer.save()
return Response({"message": "Answer updated successfully"}, status=status.HTTP_200_OK)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to update this answer."},
status=status.HTTP_403_FORBIDDEN)
def retrieve(self, request, *args, **kwargs):
# 클라이언트로부터 받은 데이터
data = request.data
# 클라이언트에서 제공한 student_id를 사용하여 User 객체를 찾기
student_id = data.get('student_id')
try:
user = User.objects.get(student_id=student_id)
except User.DoesNotExist:
return Response({"error": "User with the given student_id does not exist."},
status=status.HTTP_404_NOT_FOUND)
# URL에서 제공된 answer_id를 사용하여 해당 답변을 찾기
answer_id = kwargs.get('pk')
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
return Response({"error": "Answer not found."},
status=status.HTTP_404_NOT_FOUND)
# 답변 작성자와 현재 사용자가 일치하는지 확인
if answer.author == user:
serializer = AnswerSerializer(answer)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
# 작성자가 일치하지 않으면 오류 메시지를 반환
return Response({"error": "You do not have permission to retrieve this answer."},
status=status.HTTP_403_FORBIDDEN)
후기
viewsets.ModelViewSet
이 진짜 기능 잘 구현되어있어서 좋다.
'스펙업 > 멋쟁이사자처럼' 카테고리의 다른 글
[홈페이지 제작] 장고 백엔드 API 설정 - 질문 기능 (0) | 2023.12.24 |
---|