Получение первого и последнего связанного объекта для Django Rest API
У меня есть сериализаторы Django Rest API на основе 2 моделей, Book и Chapter
В сериализаторе Book мне нужны 2 пользовательских поля
first_chapter
last_chapter
Each имеет объекты модели Chapter
, как вы можете понять из названия поля, первый и последний объекты упорядочиваются по published_at
полю
Модель Chapter имеет внешний ключ к Book.
Я пробовал что-то вроде ниже, чтобы получить последнюю главу
class LastChapterField(serializers.RelatedField):
def get_queryset(self):
return core_models.Chapter.objects\
.filter(comic=M.OuterRef("pk"))\
.select_related("number")\
.order_by("-published_at")[:1]
Но я не вижу, чтобы последняя глава была включена в мои результаты, хотя она явно упомянута в fields
Book Serializer
Я хочу получить полный объект в возвращаемом результате, и я хочу иметь возможность использовать order by на одном из этих вложенных полей (first_chapter или last_chapter) Chapter
объекта модели.
Вы можете сделать это с помощью SerializerMethodField, который будет получать нужные вам объекты и использовать в нем другой сериализатор:
# serializers.py
from rest_framework import serializers
class ChapterSerializer(serializers.ModelSerializer):
class Meta:
model = Chapter
fields = ('published_at', 'modified_at', 'added_at',)
class BookSerializer(serializers.ModelSerializer):
first_chapter = serializers.SerializerMethodField()
last_chapter = serializers.SerializerMethodField()
def get_first_chapter(self, instance):
return ChapterSerializer(instance.chapters.order_by('published_at').first())
def get_last_chapter(self, instance):
return ChapterSerializer(instance.chapters.order_by('published_at').last())
class Meta:
model = Book
fields = ('first_chapter', 'last_chapter',
[...] # Add the other fields you want to display here
)
Затем вы можете использовать ваш сериализатор в ваших представлениях, например:
# views.py
from .serializers import BookSerializer
from .models import Book
from rest_framework.generics import RetrieveAPIView
class BookRetrieveView(RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer