无法将查询集获取到按标签匹配下降的 return 对象列表
Cant get queryset to return list of objects that is descending by tag matches
我是 运行 django 2.1.7,DRF 并使用 taggit。我正在编写自己的自定义查询集来查找对象具有的标签。
url:
示例。com/api/tags=书籍、耳机、睡眠
应该returnJSON有对象的顺序是从包含最多标签到包含至少一个标签。
这是 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
目前,我提交的这段代码有点效果,但是在提交一系列新标签时 returning 按对象 ID 和 API 端点排序的 json 获胜' 从 API 接收新的 json 转储。我现在完全迷路了。任何帮助将不胜感激。
对于 OP 来说可能为时已晚,但万一有人来看这个,在 count_matches 周围添加 Sum() 可能会成功:
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
我是 运行 django 2.1.7,DRF 并使用 taggit。我正在编写自己的自定义查询集来查找对象具有的标签。 url: 示例。com/api/tags=书籍、耳机、睡眠
应该returnJSON有对象的顺序是从包含最多标签到包含至少一个标签。 这是 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
目前,我提交的这段代码有点效果,但是在提交一系列新标签时 returning 按对象 ID 和 API 端点排序的 json 获胜' 从 API 接收新的 json 转储。我现在完全迷路了。任何帮助将不胜感激。
对于 OP 来说可能为时已晚,但万一有人来看这个,在 count_matches 周围添加 Sum() 可能会成功:
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