![](/img/trans.png)
[英]how to add annotate data in django-rest-framework queryset responses?
[英]How to order queryset based on best match in django-rest-framework?
我正在嘗試按匹配數對帶有參數的查詢結果進行排序。
例如,假設我們有一個模型:
class Template(models.Model):
headline = CharField(max_length=300)
text = TextField()
image_text = TextField(max_length=500, blank=True, null=True)
tags = TaggableManager(through=TaggedItem)
...
使用序列化程序:
class TemplateSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Template
fields = (...)
和一個視圖集:
class TemplateViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows Templates to be viewed or edited.
"""
queryset = Template.objects.all()
serializer_class = TemplateSerializer
def get_queryset(self):
queryset = Template.objects.all()
tags = self.request.query_params.getlist('tags', None)
search_text = self.request.query_params.getlist('search_text', None)
if tags is not None:
queries = [Q(groost_tags__name__iexact=tag) for tag in tags]
query = queries.pop()
for item in queries:
query |= item
queryset = queryset.filter(query).distinct()
if search_tags is not None:
queries = [Q(image_text__icontains=string) |
Q(text__icontains=string) |
Q(headline__icontains=string) for string in search_tags]
query = queries.pop()
for item in queries:
query |= item
queryset = queryset.filter(query).distinct()
我需要做的是計算過濾器找到的每個匹配項,然后按每個模板的匹配項數對查詢集進行排序。 例如:
我想找到所有在文本、圖像文本或標題中包含“hello”和“world”字符串的模板。 所以我將查詢參數“search_text”設置為hello,world 。 帶有標題 =“世界”和文本 =“大家好,大家好”的模板。 將有2 場比賽。 另一個標題為“你好”的將有1 個匹配項。 具有 2 個匹配項的模板將是查詢集中的第一個模板。 相同的行為應該適用於帶有search_text組合的標簽和標簽。
我試圖在 ViewSet 中計算這些數字,然后返回一個sorted(queryset, key=attrgetter('matches'))但遇到了 DRF 的幾個問題,比如Template 沒有屬性“matches”。 或者通過 API 直接訪問 Template 實例時出現 404。
有任何想法嗎?
嘗試annotation
,其中每個匹配對返回 1 或 0,並匯總為排名:
from django.db.models import Avg, Case, F, FloatField, Value, When
Template.objects.annotate(
k1=Case(
When(image_text__icontains=string, then=Value(1.0)),
default=Value(0.0),
output_field=FloatField(),
),
k2=Case(
When(text__icontains=string, then=Value(1.0)),
default=Value(0.0),
output_field=FloatField(),
),
k3=Case(
When(headline__icontains=string, then=Value(1.0)),
default=Value(0.0),
output_field=FloatField(),
),
rank=F("k1") + F("k2") + F("k3"),
).order_by("-rank")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.