Reputation: 23
I have a ModelViewSet
where I want to annotate the list()
response. I've extended the queryset with an annotation and added the field to the serializer, but the serializer just ignores the new data and doesn't add the field at all in the final data.
I am using a customized get_queryset()
too (show abbreviated here) which is definitely getting called and producing the right annotations. It just doesn't show up in the REST API response.
If I set default=None
on the serializer field definition, it appears in the response.
class SequenceSerializer(serializers.ModelSerializer):
unread=serializers.IntegerField(read_only=True)
.....
class SequenceViewSet(viewsets.ModelViewSet,ScopedProtectedResourceView):
authentication_classes = [OAuth2Authentication]
queryset = Sequence.objects.all()
serializer_class = SequenceSerializer
.....
def get_queryset(self):
queryset = Sequence.objects.all().filter(<..... some filter>)
queryset = queryset.annotate(unread=FilteredRelation('unreadseq',
condition=Q(unreadseq__userid=self.request.user)))
print("Seq with unread",queryset.values('id','unread')) ## <<<<this shows the correct data
return queryset
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data) ##<<< this is missing the annotation
I have been banging my head against this all day and I can't for the life of me see what's going wrong. Any ideas please?
-- more info:
class UnreadSeq(models.Model):
userid = models.ForeignKey('auth.User', on_delete=models.CASCADE)
seqid = models.ForeignKey(Sequence, on_delete=models.CASCADE)
class Meta:
unique_together=('seqid','userid')
verbose_name = "UnreadSeq"
verbose_name_plural = "UnreadSeqs"
class Sequence(models.Model):
userid = models.ForeignKey('auth.User', on_delete=models.SET_NULL,null=True)
topic = models.ForeignKey('Topic',on_delete=models.CASCADE,null=False,blank=False)
.....
class Meta:
verbose_name = "Sequence"
verbose_name_plural = "Sequences"
Upvotes: 2
Views: 1328
Reputation: 752
I think that this annotation don't return Integer. Try to annotate (you want to COUNT unreadseq) like this:
def get_queryset(self):
mytopics=getMyTopics(self.request,False)
queryset = Sequence.objects.all().filter(<..... some filter>)
count_unreadseq = Count('unreadseq', filter=Q(unreadseq__userid=self.request.user))
queryset=queryset.annotate(unread=count_unreadseq)
...
EDITED after comments to get unreadseq ids
def get_queryset(self):
mytopics=getMyTopics(self.request,False)
queryset = Sequence.objects.all().filter(<..... some filter>)
unreadseq_ids = UnreadSeq.objects.filter(seqid=OuterRef('pk'), userid=self.request.user).values('pk')
queryset=queryset.annotate(unread=Subquery(unreadseq_ids))
...
Also you need to edit serializer:
class SequenceSerializer(serializers.ModelSerializer):
unread=serializers.IntegerField(read_only=True)
.....
Upvotes: 2