Serializer relations
관계형 필드는 모델 관계를 나타내는 데 사용됩니다. 이는 ForeignKey, ManyToManyField 및 OneToOneField 관계에 적용할 수 있을 뿐만 아니라 반전 관계 및 GenericForeignKey와 같은 사용자 지정 관계에도 적용할 수 있습니다.
참고 : 관계형 필드는 Relations.py에 선언되어 있지만 규칙에 따라 from rest_framework import serializers를 사용하여 serializers 모듈에서 가져와야 하며 필드를 serializer.<FieldName>으로 참조해야 합니다.
Inspecting relationships
ModelSerializer 클래스를 사용하면 시리얼라이저 필드와 관계가 자동으로 생성됩니다. 자동으로 생성된 필드를 검사하면 관계 스타일을 사용자 지정하는 방법을 결정하는 데 유용한 도구가 될 수 있습니다.
그렇게 하려면 python manage.py shell을 사용하여 Django shell을 연다음 시리얼라이저 클래스를 가져와 인스턴스화 하고 개체 표현을 프린트합니다.
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())
API Reference
다양한 유형의 관계형 필드를 설명하기 위해 예제에 몇 가지 간단한 모델을 사용합니다. 예시로 사용될 모델은 음악 앨범과 각 앨범에 수록된 트랙이 될 것입니다.
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class Meta:
unique_together = ['album', 'order']
ordering = ['order']
def __str__(self):
return '%d: %s' % (self.order, self.title)
StringRelatedField
StringRelatedField는 str 메서드를 사용하여 관계의 대상을 나타내는 데 사용할 수 있습니다.
예를 들어 다음 시리얼라이저는 다음과 같습니다.
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.StringRelatedField(many=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
다음과 같은 형식으로 직렬화 되는것을 확인할 수 있습니다.
{
'album_name': 'Things We Lost In The Fire',
'artist': 'Low',
'tracks': [
'1: Sunflower',
'2: Whitetail',
'3: Dinosaur Act',
...
]
}
이 필드는 오직 읽기전용입니다.
아규먼트 :
- many : to-many관계에 적용되는 경우 이 아규먼트를 True로 설정해야합니다.
PrimaryKeyRelatedField
PrimaryKeyRelatedField는 기본 키를 사용하여 관계의 대상을 나타내는 데 사용할 수 있습니다.
예를 들어 시리얼라이저는 다음과 같습니다.
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
다음과 같은 형식으로 직렬화 되는 것을 확인할 수 있습니다.
{
'album_name': 'Undun',
'artist': 'The Roots',
'tracks': [
89,
90,
91,
...
]
}
기본적으로 이 필드는 읽기-쓰기이지만 read_only 플래그를 사용하여 이 동작을 변경할 수 있습니다.
아규먼트 :
- queryset - 필드 입력의 유효성을 검사할 때 모델 인스턴스 lookup에 사용되는 쿼리셋입니다. 관계는 쿼리셋을 명시적으로 설정하거나 'read_only=True
- many - to-many 관계에 적용되는 경우 이 아규먼트를 'True'로 설정해야 합니다.
- allow_null - True로 설정하면 필드에 None 값 또는 null 허용 관계에 대한 빈 문자열이 허용됩니다. 기본값은 False입니다.
- pk_field - 기본 키 값의 직렬화/역직렬화를 제어하는 필드로 설정합니다. 예를 들어 pk_field=UUIDField(format='hex')는 UUID 기본 키를 압축된 16진수 표현으로 직렬화합니다.
HyperlinkedRelatedField
HyperlinkedRelatedField는 하이퍼링크를 사용하여 관계의 대상을 나타내는 데 사용할 수 있습니다.
예를 들어 다음 시리얼라이저는 다음과 같습니다.
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.HyperlinkedRelatedField(
many=True,
read_only=True,
view_name='track-detail'
)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
다음과 같은 표현으로 직렬화됩니다.
{
'album_name': 'Graceland',
'artist': 'Paul Simon',
'tracks': [
'http://www.example.com/api/tracks/45/',
'http://www.example.com/api/tracks/46/',
'http://www.example.com/api/tracks/47/',
...
]
}
기본적으로 이 필드는 읽기-쓰기이지만 read_only 플래그를 사용하여 이 동작을 변경할 수 있습니다.
참고 : 이 필드는 lookup_field 및 lookup_url_kwarg 인수를 사용하여 설정된 단일 URL 키워드 아규먼트를 허용하는 URL에 매핑되는 개체를 위해 설계되었습니다.
이는 URL의 일부로 단일 기본 키 또는 슬러그 인수를 포함하는 URL에 적합합니다.
더 복잡한 하이퍼링크 표현이 필요한 경우 아래의 사용자 지정 하이퍼링크 필드 섹션에 설명된 대로 필드를 사용자 지정해야 합니다. 링크는 다음과 같습니다.
Arguments:
- view_name - 관계의 대상으로 사용해야 하는 view 이름입니다. 표준 라우터 클래스를 사용하는 경우 <modelname>-detail 형식의 문자열이 됩니다. 이것은 필수사항입니다.
- queryset - 필드 입력의 유효성을 검사할 때 모델 인스턴스 lookup에 사용되는 쿼리셋입니다. 관계는 쿼리셋을 명시적으로 설정하거나 read_only=True로 설정해야합니다.
- many - to-many 관계에 적용되는 경우 이 아규먼트를 True로 설정해야 합니다.
- allow_null - True로 설정하면 필드에 None 값 또는 null 허용 관계에 대한 빈 문자열이 허용됩니다. 기본값은 False입니다.
- lookup_field - lookup에 사용해야 하는 대상의 필드입니다. 참조된 view의 URL 키워드 아규먼트에 해당해야 합니다. 기본값은 'pk'입니다.
- lookup_url_kwarg - lookup필드에 해당하는 URL conf에 정의된 키워드 아규먼트의 이름입니다. 기본적으로 lookup_field와 동일한 값을 사용합니다.
- format - format 접미사를 사용하는 경우 하이퍼링크된 필드는 format 아규먼트를 사용하여 재정의하지 않는 한 대상에 대해 동일한 format 접미사를 사용합니다.
SlugRelatedField
SlugRelatedField는 대상의 필드를 사용하여 관계의 대상을 나타내는 데 사용할 수 있습니다.
예시는 다음과 같습니다.
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='title'
)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
직렬화 한 예시는 다음과 같습니다.
{
'album_name': 'Dear John',
'artist': 'Loney Dear',
'tracks': [
'Airport Surroundings',
'Everything Turns to You',
'I Was Only Going Out',
...
]
}
기본적으로 이 필드는 read-write 가능하지만 read_only 플래그를 사용하여 이 동작을 변경할 수 있습니다.
SlugRelatedField를 읽기-쓰기 필드로 사용할 때 일반적으로 슬러그 필드가 unique=True인 모델 필드에 해당하는지 확인하기를 원할 것입니다.
Arguments:
- slug_field - 대상을 나타내는 데 사용해야 하는 대상의 필드입니다. 지정된 인스턴스를 고유하게 식별하는 필드여야 합니다. 예시(사용자이름.)-required
- queryset - 필드 입력의 유효성을 검사할 때 모델 인스턴스 lookup에 사용되는 쿼리셋입니다. 관계는 쿼리셋을 명시적으로 설정하거나 read_only=True로 설정해야합니다.
- many - to-many관계에 적용되는 경우 이 아규먼트를 True로 설정해야합니다.
- allow_null - True로 설정하면 필드에 None값 또는 null 허용 관계에 대한 빈 문자열이 허용됩니다. 기본값은 False입니다.
HyperlinkedIdentityField
이 필드는 HyperlinkedModelSerializer의 'url' 필드와 같은 ID관계로 적용할 수 있습니다. 개체의 애트리뷰트에도 사용할 수 있습니다. 예를 들어 다음 시리얼라이저는 다음과 같은 값을 반환합니다.
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')
class Meta:
model = Album
fields = ['album_name', 'artist', 'track_listing']
그러면 다음과 같은 직렬화값이 나오는것을 볼 수 있습니다.
{
'album_name': 'The Eraser',
'artist': 'Thom Yorke',
'track_listing': 'http://www.example.com/api/track_list/12/',
}
이 필드는 읽기 전용 필드입니다.
아규먼트 :
- view_name - 관계의 대상으로 사용해야 하는 view이름입니다. 표준 라우터 클래스를 사용하는 경우 <model_name>-detail 형식의 문자열이 됩니다.
- lookup_field - lookup에 사용해야 하는 대상의 필드입니다. 참조된 view의 URL 키워드 아규먼트에 해당해야 합니다. 기본값은 'pk'입니다.
- lookup_url_kwarg - 조회 필드에 해당하는 URL conf에 정의된 키워드 아규먼트의 이름입니다. 기본적으로 lookup_field와 동일한 값을 사용합니다.
- format - format 접미사를 사용하는 경우 하이퍼링크된 필드는 format 아규먼트를 사용하여 재정의하지 않는 한 대상에 대해 동일한 format 접미사를 사용합니다.
Nested relationships(중첩관계)
다른 엔터티에 대해 이전에 논의된 참조와 달리 참조된 엔터티는 대신 해당 엔터티를 참조하는 개체의 표현에 폼하되거나 중첩될 수도 있습니다. 이러한 중첩 관계는 시리얼라이저를 필드로 사용하여 표현할 수 있습니다.
필드가 to-many 관계를 나타내는 데 사용되는 경우 시리얼라이저 필드에 many=True 플래그를 추가해야 합니다.
예시 코드
다음은 이것을 표현해주는 시리얼라이저입니다.
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ['order', 'title', 'duration']
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
다음과 같이 중첩된 직렬화로 표현되는것을 확인할 수 있습니다.
>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
<Track: Track object>
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
<Track: Track object>
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
<Track: Track object>
>>> serializer = AlbumSerializer(instance=album)
>>> serializer.data
{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
...
],
}
Writable nested serializers
기본적으로 중첩된 시리얼라이즈는 읽기 전용입니다. 중첩된 시리얼라이즈 필드에 대한 쓰기 작업을 지원하려면 자식 관계를 저장하는 방법을 명시적으로 지정하기 위해 create() 및/또는 update()메서드를 만들어야합니다.
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ['order', 'title', 'duration']
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
def create(self, validated_data):
tracks_data = validated_data.pop('tracks')
album = Album.objects.create(**validated_data)
for track_data in tracks_data:
Track.objects.create(album=album, **track_data)
return album
>>> data = {
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
],
}
>>> serializer = AlbumSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
<Album: Album object>
Custom relational fields
기존 관계형 스타일 중 어느 것도 필요한 표현에 맞지 않는 드문 경우에 모델 인스턴스에 출력 표현을 생성하는 방법을 정확히 설명하는 완전히 사용자 정의 관계형 필드를 구현할 수 있습니다.
사용자 정의 관계형 필드를 구현하려면 RelatedField를 재정의하고 .to_representation(self,value) 메서드를 구현해야 합니다. 이 메서드는 필드의 대상을 값 아규먼트로 사용하고 대상을 직렬화하는 데 사용해야 하는 표현을 반환해야 합니다. value 인수는 일반적으로 모델 인스턴스입니다.
읽기-쓰기 관계형 필드를 구현하려면 .to_internal_value(self,data)메서드도 구현해야합니다.
컨텍스트를 기반으로 동적 쿼리 셋을 제공하려면 클래스에서 또는 필드를 초기화할 때 .queryset을 지정하는 대신 .get_queryset(self)를 재정의할 수도 있습니다.
예시 코드
예를 들어 순서, 제목 및 기간을 사용하여 트랙을 사용자 지정 문자열 표현으로 직렬화하는 관계형 필드를 정의할 수 있습니다.
import time
class TrackListingField(serializers.RelatedField):
def to_representation(self, value):
duration = time.strftime('%M:%S', time.gmtime(value.duration))
return 'Track %d: %s (%s)' % (value.order, value.name, duration)
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackListingField(many=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
그러면 이 사용자 정의 필드는 다음 표현으로 직렬화됩니다.
{
'album_name': 'Sometimes I Wish We Were an Eagle',
'artist': 'Bill Callahan',
'tracks': [
'Track 1: Jim Cain (04:39)',
'Track 2: Eid Ma Clack Shaw (04:19)',
'Track 3: The Wind and the Dove (04:34)',
...
]
}
Custom hyperlinked fields
경우에 따라 하나 이상의 조회 필드가 필요한 URL을 나타내기 위해 하이퍼링크 필드의 동작을 사용자 지정해야 할 수도 있습니다.
HyperlinkedRelatedField를 재정의하여 이를 달성할 수 있습니다. 재정의할 수 있는 두 가지 방법이 있습니다.
get_url(self, obj, view_name, request, format)
get_url 메소드는 객체 인스턴스를 URL 표현에 매핑하는 데 사용됩니다.
view_name 및 lookup_field 애트리뷰트가 URL conf와 올바르게 일치하도록 구성되지 않은 경우 NoReverseMatch가 발생할 수 있습니다.
get_object(self, view_name, view_args, view_kwargs)
쓰기 가능한 하이퍼링크 필드를 지원하려면 들어오는 URL을 해당 URL이 나타내는 개체에 다시 매핑하기 위해 get_object도 재정의해야 합니다. 읽기 전용 하이퍼링크 필드의 경우 이 메서드를 재정의할 필요가 없습니다.
이 메서드의 반환 값은 일치하는 URL conf 인수에 해당하는 개체여야 합니다. ObjectDoesNotExist 예외가 발생할 수 있습니다.
예시
다음과 같이 두 개의 키워드 인수를 사용하는 고객 개체에 대한 URL이 있다고 가정해 보겠습니다.
/api/<organization_slug>/customers/<customer_pk>/
이것은 단일 조회 필드만 허용하는 기본 구현으로 나타낼 수 없습니다.
이 경우 원하는 동작을 얻으려면 HyperlinkedRelatedField를 재정의해야 합니다.
from rest_framework import serializers
from rest_framework.reverse import reverse
class CustomerHyperlink(serializers.HyperlinkedRelatedField):
# We define these as class attributes, so we don't need to pass them as arguments.
view_name = 'customer-detail'
queryset = Customer.objects.all()
def get_url(self, obj, view_name, request, format):
url_kwargs = {
'organization_slug': obj.organization.slug,
'customer_pk': obj.pk
}
return reverse(view_name, kwargs=url_kwargs, request=request, format=format)
def get_object(self, view_name, view_args, view_kwargs):
lookup_kwargs = {
'organization__slug': view_kwargs['organization_slug'],
'pk': view_kwargs['customer_pk']
}
return self.get_queryset().get(**lookup_kwargs)
이러한 스타일을 일반 view와 함께 사용하려면 올바른 조회 동작을 얻기 위해 view에서 .get_object를 재정의해야 합니다.
일반적으로 가능한 경우 API 표현에 플랫 스타일을 권장하지만 적당히 사용하면 중첩된 URL 스타일도 합리적일 수 있습니다.
Further notes
The queryset argument
쿼리셋 인수는 쓰기 가능한 관계 필드에만 필요하며, 이 경우 기본 사용자 입력에서 모델 인스턴스로 매핑되는 모델 인스턴스 lookup을 수행하는데 사용됩니다.
버전 2.x에서는 ModelSerializer 클래스가 사용 중인 경우 시리얼라이저 클래스가 쿼리셋 아규먼트를 자동으로 결정할 수 있었습니다.
이 동작은 이제 쓰기 가능한 관계형 필드에 대해 명시적 쿼리셋 아규먼트를 항상 사용하는 것으로 대체되었습니다.
이렇게 하면 ModelSerializer가 제공하는 숨겨진 '마법'의 양이 줄어들고 필드의 동작이 더 명확해지며 ModelSerializer 바로 가기를 사용하거나 완전히 명시적인 Serializer 클래스를 사용하여 쉽게 이동할 수 있습니다.
Customizing the HTML display
모델의 내장 str 메서드는 선택 속성을 채우는 데 상요되는 객체의 문자열 표현을 생성하는 데 사용됩니다. 이러한 선택은 탐색 가능한 API에서 HTML 입력을 선택하는 데 사용됩니다.
이러한 입력에 대한 사용자 정의 표현을 제공하려면 RelatedField 하위 클래스의 display_value()를 재정의하십시오. 이 메서드는 모델 개체를 수신하고 이를 나타내는 데 적합한 문자열을 반환해야합니다.
class TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
def display_value(self, instance):
return 'Track: %s' % (instance.title)
Select field cutoffs
탐색 가능한 API에서 렌더링될 때 관계형 필드는 기본적으로 최대 100개의 선택 가능한 항목만 표시하도록 설정됩니다. 더 많은 항목이 있는 경우 "1000개 이상의 항목.."과 함께 비활성화된 옵션이 표시됩니다.
이 동작은 표시되는 매우 많은 관계로 인해 템플릿이 허용 가능한 시간 범위 내에 렌더링할 수 없는 것을 방지하기 위한 것입니다.
이 동작을 제어하는 데 사용할 수 있는 두 가지 키워드 아규먼트가 있습니다.
- html_cutoff - 설정하면 HTML select 드롭다운에 표시되는 최대 선택 항목 수입니다. 제한을 비활성화하려면 None으로 설정합니다. 기본값은 1000입니다.
- html_cutoff_text - 설정하면 HTML select 드롭다운에서 최대 항목 수가 잘린 경우 텍스트 표시기를 표시합니다. 기본값은 "항목 {count}개이상..."
HTML_SELECT_CUTOFF 및 HTML_SELECT_CUTOFF_TEXT 설정을 사용하여 전역적으로 제어할 수도 있습니다.
컷오프가 시행되는 경우 HTML 양식에서 일반 입력 필드를 대신 사용할 수 있습니다. style키워드 인수를 사용하여 그렇게 만들 수 있습니다. 예시는 다음과 같습니다.
assigned_to = serializers.SlugRelatedField(
queryset=User.objects.all(),
slug_field='username',
style={'base_template': 'input.html'}
)
Reverse relations
역 관계는 ModelSerializer 및 HyperlinkedModelSerializer 클래스에 자동으로 포함되지 않습니다. 역 관계를 포함하려면 명시적으로 필드 목록에 추가해야 합니다.
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
fields = ['tracks', ...]
일반적으로 필드 이름을 사용할 수 있는 관계에 적절한 related_name 인수를 설정했는지 확인하고 싶을 것입니다. 예시는 다음과 같습니다.
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
fields = ['track_set', ...]
Generic relationships
일반 외래 키를 직렬화하려면 관계 대상을 직렬화하는 방법을 명시적으로 결정하기 위해 사용자 정의 필드를 정의해야 합니다.
예를 들어, 다른 임의 모델과 일반적인 관계가 있는 태그에 대해 다음 모델이 있다고 가정합니다.
class TaggedItem(models.Model):
"""
Tags arbitrary model instances using a generic relation.
See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/
"""
tag_name = models.SlugField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
tagged_object = GenericForeignKey('content_type', 'object_id')
def __str__(self):
return self.tag_name
그리고 연결된 태그가 있을 수 있는 두 모델은 다음과 같습니다.
class Bookmark(models.Model):
"""
A bookmark consists of a URL, and 0 or more descriptive tags.
"""
url = models.URLField()
tags = GenericRelation(TaggedItem)
class Note(models.Model):
"""
A note consists of some text, and 0 or more descriptive tags.
"""
text = models.CharField(max_length=1000)
tags = GenericRelation(TaggedItem)
직렬화 방법을 결정하기 위해 각 인스턴스의 유형을 사용하여 태그가 지정된 인스턴스를 직렬화하는 데 사용할 수 있는 사용자 정의 필드를 정의할 수 있습니다.
class TaggedObjectRelatedField(serializers.RelatedField):
"""
A custom field to use for the `tagged_object` generic relationship.
"""
def to_representation(self, value):
"""
Serialize tagged objects to a simple textual representation.
"""
if isinstance(value, Bookmark):
return 'Bookmark: ' + value.url
elif isinstance(value, Note):
return 'Note: ' + value.text
raise Exception('Unexpected type of tagged object')
중첩된 표현을 갖기 위해 관계의 대상이 필요한 경우 .to_representation()메서드 내에서 필요한 시리얼라이저를 사용할 수 있습니다.
def to_representation(self, value):
"""
Serialize bookmark instances using a bookmark serializer,
and note instances using a note serializer.
"""
if isinstance(value, Bookmark):
serializer = BookmarkSerializer(value)
elif isinstance(value, Note):
serializer = NoteSerializer(value)
else:
raise Exception('Unexpected type of tagged object')
return serializer.data
GenericRelation 필드를 사용하여 표현되는 역 일반 키는 관계의 대상 유형이 항상 알려져 있기 때문에 일반 관계형 필드 유형을 사용하여 직렬화할 수 있습니다.
gernericRelation에 관한 내용은 다음링크에서 확인할 수 있습니다.
링크 : https://docs.djangoproject.com/en/3.2/ref/contrib/contenttypes/#id1
ManyToManyFields with a Through Model
기본적으로 지정된 through 모델로 ManyToManyField를 대상으로 하는 관계형 필드는 읽기 전용으로 설정됩니다.
모델을 통해 ManyuToManyField를 가리키는 관계형 필드를 명시적으로 지정하는 경우 read_only를 True로 설정해야 합니다.
through 모델에서 추가 필드를 나타내려면 through 모델을 중첩 객체로 직렬화할 수 있습니다.
링크 : https://www.django-rest-framework.org/api-guide/relations/#manytomanyfields-with-a-through-model
'Django > Django REST framework' 카테고리의 다른 글
13-Testing (0) | 2021.08.24 |
---|---|
12-Validators (0) | 2021.08.18 |
10. Serializer fields (0) | 2021.07.16 |
9-3 Serializer-3 (0) | 2021.07.15 |
9-2 Serializers-2 (0) | 2021.07.15 |
댓글