I have this database setup:
class Profile(AbstractBaseUser, PermissionsMixin):
email = models.CharField(max_length=30, null=True, unique=True)
date_created = models.DateTimeField(auto_now=True) ...
class SubProfile(models.Model):
profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
display_name = models.CharField(max_length=25) ...
class SubProfilePost(models.Model):
profile = models.ForeignKey(Profile, related_name='sub_profile_postings', on_delete=models.CASCADE)
title = models.CharField(max_length=20, null=False)
looking_for_date = models.DateTimeField(null=False)
How do I now fetch the SubProfiles, and prefetch the related SubProfilePosts?
I have tried doing this:
subprofile_queryset = SubProfile.objects
select_related('profile')
prefetch_related(
Prefetch('profile__sub_profile_postings', queryset=SubProfilePost.objects.only('id', 'looking_for_date')))
When I run the queryset through my serializers:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
The data does not contain SubProfilePost(s).
If I directly access the obj.profile.sub_profile_postings.all() I can see the data.
I might be misunderstanding how prefetching works, or whether the data is annotated to the queryset when prefetching etc.
Can someone more experienced enlighten me if there is something wrong with my setup, or am I misunderstanding the whole concept.
Here are my serializers:
class ProfileSerializer(ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
extra_kwargs = {
'password': {'write_only': True, 'required': False},
}
class SubProfilePostSerializer(ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = SubProfilePost
fields = '__all__'
class SubProfileSerializer(ModelSerializer):
sub_profile_postings = SubProfilePostSerializer(many=True, read_only=True)
class Meta:
model = SubProfile
fields = [
'id',
'profile',
'display_name',
'sub_profile_postings', # Prefetched field
]
2
Answers
Implemented with SerializerMethodField.
I tried to express it as Queryset as much as possible, but I couldn’t resolve it where multiple values could be returned to the subquery.
Try this
Should return something like this, just a rough sample.
or add a getter in the
SubProfileSerializer()
to filter all theSubProfilePost
based on profile.