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?
Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.
The Python union operator can be used to combine QuerySets that belong to the same model. You can also use the chain() method from the Itertools module, which allows you to combine two or more QuerySets from different models through concatenation.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With