如何通过匹配次数与查询参数对查询结果进行排序?

时间:2019-10-23 06:15:40

标签: django-orm

我已经在this photo中进行了搜索。它按标题,描述,作者,类别搜索书籍。

我需要根据匹配数对搜索结果进行排序[matchCount

我用for循环做了一个丑陋的解决方案。最好的django方法是什么?

条件:

  1. 如果搜索参数中存在Title/Description:如果包含书名,则matchCount+=1
  2. 如果搜索参数中存在Title/Description:如果包含书籍说明,matchCount+=1
  3. 如果搜索参数中存在authorsmatchCount+=1用于书籍的每个匹配作者。
  4. 如果categories存在于搜索参数中:matchcount+=1对于书籍所属的每个匹配类别。

型号:

class Author(SafeDeleteModel):
    name = models.CharField(max_length=255)

class Category(SafeDeleteModel):
    title = models.CharField(max_length=255)

class Book(SafeDeleteModel):
    title = models.CharField(max_length=255)
    description = models.CharField(max_length=255)

    authors = models.ManyToManyField(Author)
    categories = models.ManyToManyField(Category)

查询:

filterObj = dict(request.POST)
orConditions = Q()
filterKeys = filterObj.keys()
bookTitleOrDescription = ''
authorList = categoryList = [] 
if 'bookTitleOrDescription' in filterKeys:
    bookTitleOrDescription = filterObj['bookTitleOrDescription'][0]
    orConditions = orConditions | Q(title__icontains=bookTitleOrDescription) | Q(description__icontains=bookTitleOrDescription)
if 'author[]' in filterKeys:
    authorList = filterObj['author[]']
    orConditions = orConditions | Q(authors__id__in=authorList)
if 'category[]' in filterKeys:
    categoryList = filterObj['category[]']
    orConditions = orConditions | Q(categories__id__in=categoryList)
searchedObjects = Book.objects.filter(orConditions).distinct().prefetch_related('authors','categories')

排序:

bookList = {}
for book in searchedObjects:
    matchCount = 0
    if 'bookTitleOrDescription' in filterKeys:
        if bookTitleOrDescription in book.title.lower():
            matchCount += 1
        if bookTitleOrDescription in book.description.lower():
            matchCount += 1
    if 'author[]' in filterKeys:
        for author in book.authors.all():
            if str(author.id) in authorList:
                matchCount += 1
    if 'category[]' in filterKeys:
        for category in book.categories.all():
            if str(category.id) in categoryList:
                matchCount += 1
    if matchCount not in bookList.keys():
        bookList[matchCount] = []   
    bookList[matchCount].append(book)
bookList = collections.OrderedDict(sorted(bookList.items(),reverse=True))

0 个答案:

没有答案