Reputation: 213
I have a problem with Django querying. I searched through web but still couldn't find a solution to it.
I have a model called Question:
class Question(models.Model):
...
tags = models.ManyToManyField(Tag, related_name='tagged_questions')
...
And I need to write a method which is as below:
def get_recommended_questions(request):
...
interested_tags = user.interested_tags.all()
recommended_questions_list = ... // I need help here
I need to get a list of Question
objects, which are sorted by the intersection count of their tags
with interested_tags
For example:
interested_tags = [A, B, C]
And I have following questions in the database:
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
What I want to get is:
recommended_questions_list = [q1, q3, q4]
I want to know if there is a way to do this without using raw SQL.
Thank you very much for your help!
Upvotes: 4
Views: 362
Reputation: 821
In this, first we require to get all the questions
that has any of the tag in which user is interested.
Then we can sort it based on the total matched tags
between user and question.
Sample code:
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)
Upvotes: 2
Reputation: 9931
That's long query so I will go step by step
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
Now you can sort however you want
Upvotes: 1