it-source

Django Rest-Framework 중첩된 시리얼라이저 순서

criticalcode 2023. 2. 25. 21:21
반응형

Django Rest-Framework 중첩된 시리얼라이저 순서

네스트된 시리얼라이저를 주문하는 방법이 있습니까?_set(예: 순서)pk또는time-stamp.

기본적으로는 주문입니다.song_set아래 json 데이터에 가장 최근에 생성된 개체에서 가장 최근에 생성된 개체로 표시됩니다(이 경우:order_by('-timestamp')또는order_by('-pk').

Json 데이터

{
    "pk": 151,
    "album_name": "Name",
    "song_set": [
         {
           pk: 3,
           timestamp: '5 seconds'
         },
         {
           pk: 2,
           timestamp: '10 seconds'
         },
         {
           pk: 1,
           timestamp: '15 seconds'
         }
    ]
}

모델

class Album(models.Model):
    album_name     = models.CharField(max_length=100, blank=True)


class Song(models.Model):
    album          = models.ForeignKey('album.Album', default=1)
    timestamp      = models.DateTimeField(auto_now_add=True, auto_now=False)

시리얼라이저

class SongListSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Song
        fields = [
            'pk',
            'timestamp'
        ]

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

사용할 수 있습니다.SerializerMethodField커스텀 메서드를 작성합니다.

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = serializers.SerializerMethodField()
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

    def get_song_set(self, instance):
        songs = instance.song_set.all().order_by('-timestamp')
        return SongListSerializer(songs, many=True).data

순서 메타 매개 변수를 Song 모델에 추가합니다.

class Song(models.Model):
    album = models.ForeignKey('album.Album', default=1)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)

    class Meta:
        ordering = ['timestamp', 'pk']

고객님의 고객명ViewSet, 커스텀을 사용하여 쿼리셋을 지정할 수 있습니다.Prefetch원하는 대로 필터링하고 주문할 수 있는 객체입니다.프리페치를 사용하면 (사용 시 부모 개체당 1개가 아닌) 데이터베이스 쿼리가 1개만 추가된다.SerializerMethodField퍼포먼스가 대폭 향상되었습니다.

from rest_framework import viewsets
from django.db.models import Prefetch

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.prefetch_related(Prefetch('song_set',
        queryset=Song.objects.order_by('-timestamp')))

오래된 스레드이지만, Google에서 아직 나타나고 있기 때문에, 제 대답도 공유하고 싶습니다.덮어쓰기를 시도Serializer.to_representation방법.이제 응답 정렬을 커스터마이즈하는 등 기본적으로 원하는 모든 작업을 수행할 수 있습니다.고객님의 경우:

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response["song_set"] = sorted(response["song_set"], key=lambda x: x["timestamp"])
        return response

이 문제를 해결하는 또 다른 방법으로는to_representation의 메서드ListSerializerORM을 통해 관계가 조회될 때 순서를 변경합니다.

이것.to_representationDRF의 베이스에서 동작하는 것과 비슷합니다.

class SongListSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Song
        fields = [
            'pk',
            'timestamp'
        ]

    def to_representation(self, data):
        iterable = data.all().order_by('-timestamp', '-id') \
            if isinstance(data, models.Manager) else data

        return [self.child.to_representation(item) for item in iterable]



class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

언급URL : https://stackoverflow.com/questions/48247490/django-rest-framework-nested-serializer-order

반응형