주니어 데이터 엔지니어 우솨's 개발일지

데이터 엔지니어링 15일차 TIL 본문

데브코스

데이터 엔지니어링 15일차 TIL

우솨 2024. 4. 12. 17:36

학습 내용

RelatedField

polls_api/serializers.py

questions = serializers.PrimaryKeyRelatedField(many=True, queryset=Question.objects.all())

 

유저 질문이 프라이머리키(id)로 나옴

questions = serializers.StringRelatedField(many=True, read_only=True)

 

유저 질문이 string method로 나옴

 

questions = serializers.SlugRelatedField(many=True, read_only=True, slug_field='pub_date')

필드중 아무거나 정해서 그 내용을 표시(이번엔 pubdate로 지정)

questions = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='question-detail')

 

유저 질문이 하이퍼 링크를 제공

투표기능 만들기
polls/models.py

class Vote(models.Model) :
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice = models.ForeignKey(Choice, on_delete=models.CASCADE)
    voter = models.ForeignKey(User, on_delete=models.CASCADE)

    class Meta :
        constraints = [ models.UniqueConstraint(fields=['question', 'voter'], name = 'unique_voter_for_questions')]

#투표된 갯수를 알려줌
polls_api/serializers.py
class ChoiceSerializer(serializers.ModelSerializer) :
    votes_count = serializers.SerializerMethodField()

    class Meta :
        model = Choice
        fields = ['choice_text','votes_count']

    def get_votes_count(self, obj) :
        return obj.vote_set.count()


polls_api/views.py

#내가 작성한 vote들만 보여주는 기능
class VoteList(generics.ListCreateAPIView) :
    serializer_class = VoteSerializer
    permission_classes = [permissions.IsAuthenticated] #로그인한사람만 가능

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

    def perform_create(self, serializer) :
        serializer.save(Voter=self.request.user)

#작성자만 볼 수 있음
class VoteDetail(generics.RetrieveUpdateDestroyAPIView) :
    queryset = Vote.objects.all()
    serializer_class = VoteSerializer
    permission_classes = [permissions.IsAuthenticated,IsVoter]

 


vote의 url 설정

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

polls.api/urls.py


Testing
셸에서 테스트시에 메소드 이름에 test_로 시작하는것만 실행된다.

from django.test import TestCase
from polls_api.serializers import QuestionSerializer,VoteSerializer
from django.contrib.auth.models import User
from polls.models import Question, Choice, Vote

class VoteSerializerTest(TestCase) :
    def setUp(self) :
        self.user = User.objects.create(username='testuser')
        self.question = Question.objects.create(
            question_text = 'abc',
            owner=self.user,
        )
        self.choice = Choice.objects.create(
            question = self.question,
            choice_text=['1']
        )

    #정상적인 경우의 테스트
    def test_vote_serializer(self) :
        self.assertEqual(User.objects.all().count(),1)
        data = {
            'question' : self.question.id,
            'choice' : self.choice.id,
            'voter' : self.user.id
        }
        serializer = VoteSerializer(data=data)
        self.assertTrue(serializer.is_valid())
        vote = serializer.save()

        self.assertEqual(vote.question, self.question)
        self.assertEqual(vote.choice, self.choice)
        self.assertEqual(vote.voter, self.user)

    #비정상적인 경우의 테스트
    def test_vote_serializer_with_duplicate_vote(self) :
        self.assertEqual(User.objects.all().count(),1)
        choice1 = Choice.objects.create(
            question = self.question,
            choice_text=['2']
        )
        Vote.objects.create(question=self.question, choice=self.choice, voter=self.user)

        data = {
            'question' : self.question.id,
            'choice' : choice1.id,
            'voter' : self.user.id
        }
        serializer = VoteSerializer(data=data)
        self.assertFalse(serializer.is_valid()) #유효하지 않다 False인지 확인

        
    def test_vote_serializer_with_unmatched_question_and_choice(self) :
        question2 = Question.objects.create(
            question_text = 'abc',
            owner=self.user,
        )
        choice2 = Choice.objects.create(
            question = question2,
            choice_text='1'
        )
        data = {
            'question' : self.question.id,
            'choice' : choice2.id,
            'voter' : self.user.id
        }
        serializer = VoteSerializer(data=data)
        self.assertFalse(serializer.is_valid())


class QuestionSerializerTestCase(TestCase) :
    def test_with_valid_data(self) : #vaild하게 저장되는지 테스트
        serializer = QuestionSerializer(data={'question_text' : 'abc'})
        self.assertEqual(serializer.is_valid(), True)
        new_question = serializer.save() 
        self.assertIsNotNone(new_question.id) #id가 non인지 아닌지 확인

    def test_with_invalid_data(self) : #invalid하게 저장된것 테스트
        serializer = QuestionSerializer(data={'question_text' : ''})
        self.assertEqual(serializer.is_valid(), False)

polls_api/tests.py

 

느낀 점

유저를 추가하고 유저의 기능을 관리하는 법을 배웠다.

단순히 유저의 기능만을 추가하면 여러 에러 사항이 생기는데 이에대해 대처하는 법을 알 수 있었다.

하나하나 직접 경우의 수를 구하려면 오래 걸리기 때문에 테스트라는 메소드를 사용하여 한번에 테스트 해보는 법을 배웠고 셸에서 테스트를 시험해보면서 어느 부분이 문제인지 가늠할 수 있었다.

쟝고에 대해 조금씩 알아간다는 것 같다는 생각이 들다가도 계속 새로운 내용을 배우면 어렵고 복잡하다는 생각이 다시 든다.