터칭 데이터
장고(Django) RelatedField 본문
RelatedField란?
Django의 RelatedField는 Django REST framework (DRF)에서 사용되는 직렬화 클래스의 일부로, 관련된 모델 객체에 대한 정보를 표시하고 연결된 데이터를 표현하는 데 사용되는 필드입니다. RelatedField는 다양한 관계를 다루는 데 도움이 되며, 다음과 같은 목적으로 사용됩니다:
1. **관계된 모델에 대한 정보 제공**: RelatedField는 직렬화 클래스에서 관련 모델 객체의 정보를 표시하는 데 사용됩니다. 예를 들어, ForeignKey, OneToOneField, ManyToManyField 등을 사용하여 다른 모델과의 관계를 나타내는 필드에 대한 데이터를 표시할 때 사용됩니다.
2. **연결된 데이터 표현**: RelatedField를 사용하면 연결된 모델의 데이터를 원하는 방식으로 직렬화할 수 있습니다. 이를 통해 연결된 모델의 필드를 선택하거나, 특정 필드의 데이터를 조작하거나, 필드의 표현 방식을 사용자 정의할 수 있습니다.
3. **하이퍼링크 관계 표현**: RelatedField를 사용하여 API에서 하이퍼링크로 관계를 표현할 수 있습니다. 예를 들어, 다른 모델 객체에 대한 URL을 제공하여 클라이언트가 해당 객체에 대한 자세한 정보를 가져오도록 할 수 있습니다.
4. **관련 객체의 ID 참조**: RelatedField를 사용하여 연결된 모델 객체의 ID를 참조하거나 표시할 수 있으며, 이를 통해 연결된 객체를 고유하게 식별할 수 있습니다.
간단히 말하면, RelatedField는 DRF에서 관련된 모델 객체와 그 데이터를 다루는 데 사용되는 유연한 필드입니다. 이를 통해 API에서 관련된 데이터를 표현하고 제어할 수 있으며, 연결된 모델의 정보를 클라이언트에게 제공할 때 유용합니다.
StringRelatedField
사용자 User들에 대한 정보를 조회하는 User List 페이지를 보겠습니다.
우리는 지난 시간 user1으로 로그인해 id가 10인 question을 하나 작성한 적이 있습니다. 이를 이미지에서 확인할 수 있는데요. 여기에서 questions의 작성해온 질문 목록들을 숫자 id 대신 다른 것으로 대체할 수 있습니다.
polls_api/serializers.py
class UserSeralizer(serializers.ModelSerializer):
# questions = serializers.PrimaryKeyRelatedField(many=True, queryset=Question.objects.all())
questions = serializers.StringRelatedField(many=True, read_only=True)
class Meta:
model = User
fields = ['id', 'username', 'questions']
주석처리된 부분은 우리가 기존에 사용하던 PrimaryKeyRelatedField입니다. 이를 StringRelatedField로 바꿉니다.
Django의 serializers 모듈에서 StringRelatedField는 관계 필드 (예: ForeignKey, OneToOneField, ManyToManyField)와 함께 사용되며, 연결된 모델의 관련 객체를 문자열로 표현하는 데 사용됩니다. 이 필드는 다음과 같은 역할을 합니다:
연결된 모델 객체를 문자열로 표현: StringRelatedField를 사용하면 연결된 모델의 관련 객체를 해당 객체의 __str__() 메서드의 반환 값으로 표현합니다. 일반적으로 이는 연결된 모델의 기본 문자열 표현인 "str()" 메서드의 결과입니다.
polls/models.py
StringRelatedField덕에 우리가 Question 모델을 정의할 때 작성한 __str__ 메서드가 return한 대로 사용자가 그동안 작성한 question들을 확인할 수 있다는 뜻입니다. 즉 더 이상 단순한 question id로 확인하지 않는다는 뜻이죠.
브라우저에서 새로고침시
아까와 다르게 더 명확하고 보기 편합니다.
SlugRelatedField
polls_api/serializers.py
class UserSeralizer(serializers.ModelSerializer):
questions = serializers.SlugRelatedField(many=True, read_only=True, slug_field='pub_date')
class Meta:
model = User
fields = ['id', 'username', 'questions']
이번에는 StringRelatedField를 SlugRelatedField로 바꿨습니다.
한줄로 요약하면 모델의 필드들 중에서 원하는 필드를 아무것이나 자유롭게 지정해 그 내용을 표시한다고 생각하시면 됩니다. 위의 코드에서는 pub_date 필드를 표시한다고 지정해줬습니다.
`serializer.SlugRelatedField`는 Django REST framework (DRF)에서 사용되는 직렬화 필드 중 하나로, 연결된 모델의 Slug 필드를 사용하여 관련 객체를 나타내는 데 사용됩니다. 이 필드는 일반적으로 ForeignKey 또는 OneToOneField와 함께 사용되며, 연결된 모델의 Slug 값을 기반으로 연결된 객체를 참조합니다.
Slug은 일반적으로 URL에서 사용되는 문자열로, 공백이나 특수 문자 대신 하이픈이나 밑줄로 단어를 구분하는데 사용됩니다. Slug 필드는 주로 URL을 생성하거나 검색 엔진 최적화를 위한 인덱스 키로 사용됩니다.
`SlugRelatedField`의 역할은 다음과 같습니다:
1. **연결된 객체의 Slug 값 참조**: `SlugRelatedField`를 사용하면 연결된 모델의 Slug 값을 기반으로 해당 모델의 객체를 참조할 수 있습니다. 이 필드를 사용하면 클라이언트가 Slug 값을 제공하여 연결된 객체를 식별할 수 있습니다.
2. **Slug 필드를 사용한 표현**: API 응답에서 관련 객체를 나타낼 때 Slug 필드의 값을 사용합니다. 이를 통해 클라이언트는 Slug 값을 통해 연결된 객체를 이해하고 인식할 수 있습니다.
예를 들어, 다음은 `Book` 모델과 `Author` 모델 간의 관계에서 `author` 필드를 표현하는데 `SlugRelatedField`를 사용하는 방법을 보여줍니다:
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
author = serializers.SlugRelatedField(
queryset=Author.objects.all(),
slug_field='slug' # 연결된 모델의 Slug 필드 이름
)
class Meta:
model = Book
fields = '__all__'
위의 코드에서 `author` 필드는 `SlugRelatedField`로 설정되었으며, `queryset` 인자로 `Author` 모델의 모든 객체를 가져옵니다. 이를 통해 클라이언트는 `author` 필드를 통해 저자의 Slug 값을 제공하여 책과 연결된 저자를 식별할 수 있습니다.
`SlugRelatedField`는 Slug 값을 기반으로 관련 객체를 참조하고 표현할 때 유용하며, 특히 API에서 Slug을 사용하여 객체를 식별하는 경우에 활용됩니다.
pub_date만 표현됩니다.
HyperlinkedRelatedField
그런데 위에서 작성한 question을 클릭하면 그 question의 상세 페이지로 갈 수 있다면 좋을 것 같지 않나요?
이런 링크를 제공해주는 것이 바로 HyperlinkedRelatedField입니다.
polls_api/serializers.py
class UserSeralizer(serializers.ModelSerializer):
questions = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='question_detail')
class Meta:
model = User
fields = ['id', 'username', 'questions']
클릭시 해당 링크로 이동하도록해야 하기 때문에 view_name에 question의 상세 페이지 URL의 별칭인 question_detail을 주도록 하겠습니다.
polls_api/urls.py
지난 실습때 question_detail을 URL 별칭으로 주었습니다.
커서를 올리면 링크가 걸립니다.
클릭을 하면 해당 question의 상세 페이지까지 잘 이동한 것을 볼 수 있습니다.
Question 상세 페이지에서 choice의 choice_text와 votes까지 조회하기
User뿐만 아니라 Question의 상세 페이지에서도 해당 Quesiton이 어떤 선택지들을 갖고 있는지 choice들의 내용과 그 동안의 득표수 까지 볼 수 있으면 더 좋을 것 같습니다.
polls_api/serializers.py
ChoiceSerializer를 새로 정의하고 QuestionSerializer에서 choice_set으로 관련된 choice들을 가져올 수 있도록 한 다음 fileds에 'choice_set' 필드를 추가했습니다.
새로고침을 하니 "커피 vs 녹차 선택은?"의 question에 관련된 choice들인 커피와 녹차가 득표수까지 함께 조회됩니다.
choice가 없는 question의 상세 페이지는 위와 같이 [] 빈 리스트가 출력됩니다.
필드명 변경하기
그런데 choice들을 조회할 때 파란색 박스안에 있는 choice_set의 이름을 바꿔주고 싶은데 가능할까요?
모델에서 역참조를 진행할 때 사용할 related_name을 원하는 대로 지정해주면됩니다.
만약 지정하지 않는다면 choice_set이나 question_set과 같이 소문자모델명언더바set으로 표현한다고 했었습니다.
polls/models.py
related_name을 choices로 지정합니다. 위의 블록을 보면 우리가 지난 시간 User에서 Question으로 역참조를 할 때 사용할 related_name을 questions로 지정했었던 걸 볼 수 있습니다.
polls/serializers.py
related_name을 choices로 지정했으므로 기존에 Serializer에서 choice_set으로 적혔던 부분을 choices로 바꿔줍니다.
브라우저를 새로고침하면
choice_set에서 choices로 잘 변경되었습니다.
'장고 (Django)' 카테고리의 다른 글
장고(Django) 투표(Votes) 기능 구현하기 2 - Serializers & Views (0) | 2023.11.05 |
---|---|
장고(Django) 투표(Votes) 기능 구현하기 1 - Models (0) | 2023.11.05 |
장고(Django) User 권한 관리 (0) | 2023.11.05 |
장고(Django) Serializer를 사용하여 User 생성하기 (0) | 2023.11.05 |
장고(Django) Form을 사용하여 User 생성하기 (0) | 2023.11.05 |