Аннотированный набор запросов django игнорируется во время сериализации - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть ModelViewSet, где я хочу аннотировать ответ list().Я расширил набор запросов аннотацией и добавил поле в сериализатор, но сериализатор просто игнорирует новые данные и вообще не добавляет поле в окончательные данные.

Я использую настроенныйget_queryset() тоже (показать сокращенно здесь), который определенно вызывается и производит правильные аннотации.Он просто не отображается в ответе REST API.Если я установлю default=None в определении поля сериализатора, оно появится в ответе.

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

Я весь день бился с этим, и я не могу, как я понимаю, что происходитнеправильно.Есть идеи, пожалуйста?

- больше информации:

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"

1 Ответ

0 голосов
/ 13 декабря 2018

Я думаю, что эта аннотация не возвращает Целое число .Попробуйте аннотировать (вы хотите COUNT unreadseq) следующим образом:

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 после комментариев, чтобы получить непрочитанные идентификаторы

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))
    ...

Также вам нужно отредактировать сериализатор:

class SequenceSerializer(serializers.ModelSerializer):
    unread=serializers.IntegerField(read_only=True)
    .....
...