Django Shell로 확인
>>> from api2.serializers import *
>>> PostRetrieveSerializer()
PostRetrieveSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(label='TITLE', max_length=50)
description = CharField(allow_blank=True, help_text='simple one-line text.', label='DESCRIPTION', max_length=100, required=False)
image = ImageField(allow_null=True, label='IMAGE', max_length=100, required=False)
content = CharField(label='CONTENT', style={'base_template': 'textarea.html'})
update_dt = DateTimeField(label='UPDATE DT', read_only=True)
like = IntegerField(label='LIKE', required=False)
category = PrimaryKeyRelatedField(allow_null=True, queryset=Category.objects.all(), required=False)
tags = PrimaryKeyRelatedField(many=True, queryset=Tag.objects.all(), required=False)
PrimaryKeyRelatedField
로 잡혀있기 때문에 출력시 pk로 나오는 것! ForeignKey
필드ManyToManyField
필드ForeignKey
필드와 ManyToManyField
에 대해서 DRF에서는 자동으로 PrimaryKeyRelatedField
로 잡아줌!DRF 공식문서 확인 (Serializer relations)
DRF에서 ForeignKey, ManyToManyField, OneToOneField, GenericForeignKey 필드를 사용하는 경우 StringRelatedField
⭐, PrimaryKeyRelatedField
⭐, HyperlinkedRelatedField
, SlugRelatedField
, HyperlinkedIdentityField
등을 사용할 수 있음!
PrimayrKeyRelatedField⭐
StringRelatedField⭐
__str__
메서드에 표현된(정의된) 문자열임!기존에 정의된 models.py
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
description = models.CharField('DESCRIPTION', max_length=100, blank=True, help_text='simple one-line text.')
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
__str__(self)
메서드에 name 속성을 사용하고 있으므로, StringRelatedField
를 사용하면 pk가 아닌 name으로 표현 가능!serializers.py 수정 : PostRetrieveSerializer
class PostRetrieveSerializer(serializers.ModelSerializer):
# 기존의 필드를 serializer 내부에서 오버라이딩하여 사용⭐
category = serializers.StringRelatedField()
tags = serializers.StringRelatedField(many=True)
class Meta:
model = Post
# fields = '__all__'
exclude = ['create_dt']
tags = serializers.StringRelatedField(many=True)
: Tag는 List 형식으로 복수(ManyToManyField)로 사용되기 때문에 many=True 인자 필요!veiws.py : 데이터를 공급해주는 view는 변경사항이 없음. 수정X (→ 출력 형식만 바뀌는 것이기 때문!)
views.py : get_serializer_context(self)
메서드 오버라이딩
def get_prev_next(instance):
try:
prev = instance.get_previous_by_update_dt()
except instance.DoesNotExist:
prev = None
try:
next_ = instance.get_next_by_update_dt()
except instance.DoesNotExit:
next_ = None
return prev, next_
class PostRetrieveAPIView(RetrieveAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializerDetail
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
prevInstance, nextInstance = get_prev_next(instance)
commentList = instance.comment_set.all()
data = {
'post' : instance,
'prevPost' : prevInstance,
'nextPost' : nextInstance,
'commentList' : commentList,
}
serializer = self.get_serializer(instance=data)
return Response(serializer.data)
# override
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': None,
'format': self.format_kwarg,
'view': self
}
https://www.django-rest-framework.org/api-guide/relations/#stringrelatedfield
https://www.inflearn.com/course/%EC%9E%A5%EA%B3%A0-drf/dashboard