dev course - DE/TIL
[데브코스] TIL 15일차
nani-jin
2024. 4. 16. 18:01
RelatedField
- polls_api/serializers.py
from rest_framework import serializers
from polls.models import Question, Choice
from django.contrib.auth.models import User
from django.contrib.auth.password_validation import validate_password
# Choice에 대한 Serializer
class ChoiceSerializer(serializers.ModelSerializer):
class Meta:
model = Choice
fields = ['choice_text', 'votes']
class QuestionSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username') # owner를 고르지 못하고, 읽기만하게
choices = ChoiceSerializer(many=True, read_only=True)
class Meta:
model = Question
fields = ['id','question_text','pub_date','owner','choices']
class UserSerializer(serializers.ModelSerializer):
# 내아이디로 불러올 수 있는 question을 명시해야함
# PrimaryKeyRelatedField(출력이 pk값으로 표시됨)-> StringRelatedField(출력이 String으로 표시됨. __str__에 정의되어있는...)
# SlugRelatedField(questions 내용에 있는 것 중 아무거나 정해서 표시할 수 있음)
# HyperlinkedRelatedField(해당 url로 이동)
questions = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='question-detail') # many=True : 리스트 형식으로 복수개
class Meta:
model = User
fields = ['id','username','questions']
- polls_api/urls.py
...
class Choice(models.Model):
question = models.ForeignKey(Question, related_name='choices', on_delete=models.CASCADE) # choice_set 대신 choices로 불러오기 위해
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return f'[{self.question.question_text}] {self.choice_text}'
models - 투표(votes) 기능 구현
- polls/model.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() # SerializerMethodField : 메서드에 의해 값이 정의됨
class Meta:
model = Choice
fields = ['choice_text','votes_count']
def get_votes_count(self, obj):
return obj.vote_set.count() # 별도의 Forienkey를 정의하지 않으면 _set으로 가져올 수 있음
- shell
serializers & views - 투표(votes) 기능 구현
직접 vote을 누를 수 있게