Django REST Framework: Как использовать префетчированные наборы запросов в дочерних сериализаторах во вложенных сериализаторах
Я хочу вызвать queryset, предварительно извлеченный из View, из вложенного дочернего сериализатора. Я попробовал сделать следующее, но это не сработало так, как я задумал. Как я могу вызвать предварительно выбранный кверисет из дочернего сериализатора?
#views.py
class PlaylistListView(generics.ListAPIView):
serializer_class = PlaylistSerializer
def get_queryset(self):
return (
Playlist.objects.all()
.prefetch_related("user", "user__emailaddress_set")
)
#serializers.py
class UserDetailSerializer(serializers.ModelSerializer):
is_verified = serializers.SerializerMethodField()
class Meta:
model = User
fields = ("is_verified",)
def get_is_verified(self, user):
return user.emailaddress_set.filter(verified=1).count() > 0
class PlaylistSerializer(serializers.ModelSerializer):
user = UserDetailSerializer(read_only=True)
class Meta:
model = Playlist
fields = ("user",)
Мы можем использовать объект Prefetch
для предварительной выборки пользователей с аннотацией о том, проверен он или нет, verified
, похоже, является булевой функцией, поэтому выбор Max
даст нам True
, если все связанные электронные письма проверены. В сериализаторе мы можем искать эту аннотацию и, если она существует, возвращать ее, иначе возвращается то же самое, что и раньше
from django.db.models import Prefetch, Max
class PlaylistListView(generics.ListAPIView):
serializer_class = PlaylistSerializer
def get_queryset(self):
return Playlist.objects.prefetch_related(
Prefetch('user', queryset=User.objects.annotate(_is_verified=Max('emailaddress__verified')))
)
class UserDetailSerializer(serializers.ModelSerializer):
is_verified = serializers.SerializerMethodField()
class Meta:
model = User
fields = ("is_verified",)
def get_is_verified(self, user):
if hasattr(user, "_is_verified"):
return user._is_verified
else:
return user.emailaddress_set.filter(verified=True).exists()