Django通过属性与另一个QuerySet的交集计数对模型对象进行排序

时间:2018-02-22 07:25:05

标签: python django

我有Django查询的问题。我通过网络搜索但仍无法找到解决方案。

我有一个名为Question的模型:

class Question(models.Model):
    ...
    tags = models.ManyToManyField(Tag, related_name='tagged_questions')
    ...

我需要编写一个如下方法:

def get_recommended_questions(request):
    ...
    interested_tags = user.interested_tags.all()
    recommended_questions_list = ... // I need help here

我需要获取Question个对象的列表,这些对象按其tagsinterested_tags

的交集计数排序

例如:

interested_tags = [A, B, C]

我在数据库中有以下问题:

q1.tags = [A, B, C] // intersection count = 3
q2.tags = [D] // intersection count = 0
q3.tags = [A, B, D] // intersection count = 2
q4.tags = [A, D] // intersection count = 1

我想得到的是:

recommended_questions_list = [q1, q3, q4]

我想知道是否有办法在不使用原始SQL的情况下执行此操作。

非常感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

在此,首先我们要求获得具有用户感兴趣的任何标记的所有questions。 然后我们可以根据用户和问题之间的总匹配tags对其进行排序。

示例代码:

interested_tags_ids = user.interested_tags.all().values_list('id', flat=True)
questions = Question.objects.filter(tags__in=interested_tags_ids).prefetch_related('tags')
interested_tags_set = set(interested_tags_ids)

sort_func = lambda question: len(set(question.tags.all().values_list('id', flat=True)) & interested_tags_set)
recommended_questions_list = sorted(questions, key=sort_func, reverse=True)

答案 1 :(得分:1)

这是一个很长的查询,所以我将一步一步地进行

def get_recommended_questions(request):
    ...
    interested_tags = user.interested_tags.all()
    questions = Question.objects.all()
    recommended_questions_list = [(question, 
             len(set(interested_tags)&set(list(question.tags.all())))) 
             for question in questions]
    # the above list has tuples with question object and intersection count

现在您可以根据需要进行排序