How to combine multiple querysets and remove duplicates?
Asked Answered
E

1

10

I'm using Django 1.6.1 with django-taggit.

I'm trying to extend my search engine so that it searches for keywords in other fields besides the tag fields. The trouble is that when I iterate through the tags for an icontains search in the model's name, the queryset seems to cease being a queryset, losing its count method, and the distinct method doesn't work.

views.py:

def index(request):
    numresources = Resource.objects.count()

    if request.method == 'POST':
        form = SearchForm(request.POST)
        if form.is_valid():
            query = form.cleaned_data['query']
            tags = parse_tags(query.lower())

#            resourcelist = []
#            for tag in tags:
#                resourcelist.extend(Resource.objects.filter(name__icontains=tag).filter(isActive=True).order_by('-score').distinct())
#            resourcelist.extend(Resource.objects.filter(tags__name__in=tags).filter(isActive=True).order_by('-score').distinct())
#            numresults = len(resourcelist)

            resourcelist = Resource.objects.filter(tags__name__in=tags).filter(isActive=True).order_by('-score').distinct()
            querymade = True
            numresults = resourcelist.count()
        else:
            resourcelist = Resource.objects.filter(isActive=True).order_by('-created')[:100]
    else:
        resourcelist = Resource.objects.filter(isActive=True).order_by('-created')[:100]
        form = SearchForm()

    return render(request, 'index.html', locals())

It seems clunky to have to add the 'django' keyword to a record that has 'django' in the title or url. I want to have not only the results whose tags match the keywords the user entered, but I want to search other fields for the keywords entered, combine those querysets, and leave on of any result added twice or more.

So how and when in this process do I sort by score and then remove duplicates?

Err answered 9/1, 2014 at 7:21 Comment(0)
D
10

I think that you want something like this:

from django.db.models import Q

Resource.objects.filter(Q(name__icontains=tag) | Q(tags__name__in=tags)).filter(isActive=True).order_by('-score').distinct()

Q objects documentation

Darius answered 9/1, 2014 at 7:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.