18. 투표(Votes) 기능 구현하기 2 - Serializers & Views

data_hamster·2023년 4월 30일
0
post-custom-banner

학습주제
투표(Votes) 기능 구현하기

학습내용
지난시간 Choice의 Foreignkey를 이용해서 vote의 숫자를 계산하는 메소드를 이용한 votes_count 필드를 작성하였다.

이번엔 직접 Vote를 만들 수 있는 시리얼라이저와 뷰를 구현해 보려고 한다.

시리얼라이저에서

class VoteSerializer(serializers.ModelSerializer):
    voter = serializers.ReadOnlyField(source='voter.username')	

    class Meta:
        model = Vote
        fields = ['id', 'question', 'choice', 'voter']

voter는 읽기 전용으로 생성해준다. (수정불가)
필즈도 정의해준다.

뷰로 이동
vote를 만들 수 있는 뷰를 만드는데 List형과 Detail 둘다 만든다. 수정도 해야하기 때문에 Detail도 필요함.

class VoteList는 QuestionList와 유사하다.
IsAuthenticated는 로그인을 안했을 경우, 조회기능도 제공하지 않음
vote같은 경우는 아무 vote나 보여주어선 안됨. 내가 한 vote만 보여주어야 함. 이런 조건을 적용할 List를 보여줄 queryset를 정의해주어야 한다. 이는 def get_queryset를 이용한다
class GenericAPIView(views.APIView):에 있는 get_queryset을 오버라이딩 한 것.

class VoteList(generics.ListCreateAPIView):
    serializer_class = VoteSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self, *args, **kwargs):
        return Vote.objects.filter(voter=self.request.uesr)

class VoteDetail은 QuestioDetail과 유사,
모든 vote를 불러오는데
Update와 Delete는 내가 한 투표에 대해서만 접근 가능해야한다.
permissions.IsAuthenticated 외에 그러한 기능을 하는 클래스를 추가한다
QuestionDetail때는 permissions.py를 구현하여, 해당 유저만 업데이트, 삭제를 할 수 있게 했었다.

permissions.py로 이동해 비슷한걸 만들어준다.

class IsVoter(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.voter == request.user
class VoteDetail(generics.RetrieveUpdateDestroyAPIView):    
    queryset = Vote.objects.all()
    serializer_class = VoteSerializer
    permission_classes = [permissions.IsAuthenticated, IsVoter]

이렇게 로그인, 작성자만 접근할 수 있게 되었다.

또한 VoteList에서 생성을 담당하기 때문에, 여기서 투표를 했을 경우, 그 Vote내부의 voter에 현재 접속한 사용자가 넘어가도록 한다.

url을 연결한다

    path('vote/', VoteList.as_view()),
    path('vote/<int:pk>/', VoteDetail.as_view()),


처음에 오류났었음. uesr을 user로 정정.


Vote List에서 하단에 질문과 답안을 선택할 수있다. 아직 보니까 choice는 어떤 것이든 다 선택할 수 있게 되어 있었다.
생성된 후, 다시 돌아가보니 정상적으로 반영되어 있다.

만일 question에 연결되지 않은 choice를 선택하면 이런 에러가 난다.

profile
반갑습니다 햄스터 좋아합니다
post-custom-banner

0개의 댓글