0

Here are my models and the manager class. I think the problem is in the PostingFilterManager below. They way I search of the keywords in title and body_text is wrong. I want to query for a list of keywords in title and body_text of Postings model below. I am not getting any error but at the same time nothing is displayed on browser. I am sure that the filter should return a posting.

class PostingFilterManager(models.Manager):
   def get_by_keywords(self,wordlist):
        print "called"
        posts=super(PostingFilterManager,self).get_query_set().filter
        (Q(body_text__in=wordlist) | Q(title__in=wordlist))
        print posts
        return posts

class Postings(models.Model):
    carinfo=models.ForeignKey('CarInfo')
    title = models.CharField(max_length=100, blank=True)
    body_text = models.TextField(blank=True)    
    objects=models.Manager()
    filters=PostingFilterManager()

    def __unicode__(self):
        return unicode(self.website)

my view:

def detail(request,year):
    result=Postings.filters.get_by_keywords(['hello'.'world','clean'])
    return HttpResponse(result)
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • `...filter(CarInfo.objects.filter(year__lte=year))` — don't you mean `...filter(carinfo__in=CarInfo.objects.filter(year__lte=year))`? – lanzz Mar 28 '14 at 23:22
  • @lanzz: That helped thanks. but I have related problem which I edited on this question. my view passes a list of keywords to the Manager Object, which in turn should filter the title and body for these keywords, I am not getting this to work correctly, please help – brain storm Mar 28 '14 at 23:37
  • Are you copying and pasting your code here, or are you typing it again by hand? Because `['hello'.'world','clean']` would throw a `SyntaxError` exception due to the dot between `'hello'` and `'world'`. – lanzz Mar 30 '14 at 12:57

1 Answers1

1

This won't work because of how you constructed query. Let's analyze your query:

filter(Q(body_text__in=wordlist) | Q(title__in=wordlist))

It seems you want to search for keywords in content and titles. But body_text__in=wordlist means that filter will be satisfied if your whole body of text will be either 'hello' or 'world' or 'clean.' My assumption is that it's not what you want. Instead what you are looking for is iterating over keywords and using __contains condition. I haven't written Django queries in quite a while, so I will write some ugly code that maybe will present the general idea:

full_query = null
for keyword in wordlist:
  if full_query is null:
    full_quey = Q(body_text__contains=keyword) | Q(title__in=keywords)
  else:
    full_query = full_query | (Q(body_text__contains=keyword) | Q(title__in=keywords))
posts=super(PostingFilterManager,self).get_query_set().filter
        (Q(body_text__in=wordlist) | Q(title__in=wordlist))

Also, additional suggestion. What you are doing here is full text search and what you are doing is probably not the best way of doing it. Probably a better way would be to construct an index and search an index.

Consider reading Wikipedia article about full text search, especially indexing: http://en.wikipedia.org/wiki/Full_text_search

gruszczy
  • 40,948
  • 31
  • 128
  • 181
  • Thanks for the reply. can you please elaborate what you mean by construct and index and search for the index. or any links that explains this? Thanks – brain storm Mar 31 '14 at 00:28
  • I added wikipedia article, which should give you a basic overview. – gruszczy Mar 31 '14 at 16:34