无法获取查询集以返回按标签匹配降序的对象列表

问题描述 投票:0回答:1

我正在运行django 2.1.7,DRF并使用taggit。我正在编写自己的自定义查询集来查找对象具有的标签。网址:example.com/api/tags=书,耳机,睡眠

应返回JSON,该JSON的对象顺序为:从包含大多数标签到包含至少一个标签。这是gitgist

from django.db.models import Case, ExpressionWrapper, IntegerField, Q, Value, When

class SpecialSearch(ListAPIView):
    model = Object
    serializer_class = ObjectSerializer

    def get_queryset(self, rs, value):
        """
        Recipe search matching, best matching and kind of matching,
        by filtering against `tags` query parameter in the URL.
        """
        if value:
            tags = [tag.strip() for tag in value.split(',')]
            qs = Object.objects.filter(
                reduce(
                    lambda x, y: x | y, [Q(tags__icontains=tag) for tag in tags]))
            check_matches = map(
                lambda x: Case(
                    When(Q(tags__icontains=x), then=Value(1)),
                        default=Value(0)),
            tags)
            count_matches = reduce(lambda x, y: x + y, check_matches)
            qs = qs.annotate(
            matches=ExpressionWrapper(
                count_matches,
                output_field=IntegerField()))
            qs = qs.order_by('-matches')
        return qs

[当前,此代码我提交了一些作品,但是在提交一系列新标签时,返回的是由对象ID和API端点排序的json,不会从API收到新的json转储。我现在完全迷路了。任何帮助将不胜感激。

django rest django-rest-framework drf-queryset
1个回答
0
投票
from django.db.models import (Case, ExpressionWrapper, IntegerField, Q, Value, When, Sum) class SpecialSearch(ListAPIView): model = Object serializer_class = ObjectSerializer def get_queryset(self, rs, value): """ Recipe search matching, best matching and kind of matching, by filtering against `tags` query parameter in the URL. """ if value: tags = [tag.strip() for tag in value.split(',')] qs = Object.objects.filter( reduce( lambda x, y: x | y, [Q(tags__icontains=tag) for tag in tags])) check_matches = map( lambda x: Case( When(Q(tags__icontains=x), then=Value(1)), default=Value(0)), tags) count_matches = reduce(lambda x, y: x + y, check_matches) qs = qs.annotate( matches=ExpressionWrapper( Sum(count_matches), output_field=IntegerField())) qs = qs.order_by('-matches') return qs
© www.soinside.com 2019 - 2024. All rights reserved.