Django and Haystack search issue
I am running Python 2.6, the lastest haystack, django 1.2 beta and I have tried both Woosh and Xapian backends.
The problem is that I cannot do a __lt or __gt filter on an integer field - when such is used,there are always none results found...
My model:
# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext as _
from django.forms import ModelForm
from django.contrib.auth.models import User
# Create your models here.
class District(models.Model):
name = models.CharField(_('STRING_DISTRICT'),max_length=100)
def __unicode__(self):
return u'%s' % self.name
class City(models.Model):
district = models.ForeignKey(District)
name = models.CharField(_('STRING_CITY'),max_length=100)
def __unicode__(self):
return u'%s -> %s' % (self.district.name,self.name)
class Status(models.Model):
name = models.CharField(_('STATUS_NAME'),max_length=50)
def __unicode__(self):
return u'%s' % self.name
class Source(models.Model):
name = models.CharField(_('SOURCE_NAME'),max_length=50)
def __unicode__(self):
return u'%s' % self.name
class SpaceUnit(models.Model):
name = models.CharField(_('SPACE_UNIT_NAME'),max_length=50)
def __unicode__(self):
return u'%s' % self.name
class Currency(models.Model):
name = models.CharField(_('CURRENCY_NAME'),max_length=50)
def __unicode__(self):
return u'%s' % self.name
class EstateType(models.Model):
name = models.CharField(_('ESTATE_TYPE'),max_length=50)
def __unicode__(self):
return u'%s' % self.name
class Client(models.Model):
owner = models.ForeignKey(User)
name = models.CharField(_('STRING_NAME'),max_length=50)
surname = models.CharField(_('STRING_SURNAME'),max_length=50)
code = models.CharField(_('STRING_PID_REG_NR'),max_length=50,blank=True)
status = models.ForeignKey(Status,blank=True)
source = models.ForeignKey(Source,blank=True)
district = models.ForeignKey(District)
city = models.ForeignKey(City)
mobile_phone = models.CharField(_('STRING_MOBILE_PHONE_PERSONAL'),max_length=15,blank=True)
home_phone = models.CharField(_('STRING_HOME_PHONE'),max_length=15,blank=True)
work_phone = models.CharField(_('STRING_WORK_PHONE'),max_length=15,blank=True)
work_mobile_phone = models.CharField(_('STRING_WORK_MOBILE_PHONE'),max_length=15,blank=True)
agreement_nr = models.CharField(_('STRING_AGREEMENT_NR'),max_length=50,blank=True)
email_private = models.CharField(_('STRING_EMAIL_PRIVATE'),max_length=100,blank=True)
estate_type = models.ForeignKey(EstateType)
wants_to_rent = models.BooleanField(_('STRING_WANTS_TO_RENT'),blank=True)
rental_space_from = models.IntegerField(_('STRING_SPACE_FROM'),max_length=5)
rental_space_until = models.IntegerField(_('STRING_SPACE_UNTIL'),max_length=5)
rental_space_units = models.ForeignKey(SpaceUnit,related_name="rental_space_units")
rental_price_from = models.IntegerField(_('STRING_PRICE_FROM'),max_length=5)
rental_price_until = models.IntegerField(_('STRING_PRICE_UNTIL'),max_length=5)
rental_price_units = models.ForeignKey(Currency,related_name="rental_currency_units")
wants_to_buy = models.BooleanField(_('STRING_WANTS_TO_BUY'),blank=True)
buying_space_from = models.IntegerField(_('STRING_SPACE_FROM'),max_length=5)
buying_space_until = models.IntegerField(_('STRING_SPACE_UNTIL'),max_length=5)
buying_space_units = models.ForeignKey(SpaceUnit,related_name="buying_space_units")
buying_price_from = models.IntegerField(_('STRING_PRICE_FROM'),max_length=5)
buying_price_until = models.IntegerField(_('STRING_PRICE_UNTIL'),max_length=5)
buying_price_units = models.ForeignKey(Currency,related_name="buying_currency_units")
def __unicode__(self):
return u'%s %s' % (self.name,self.surname)
class ClientForm(ModelForm):
class Meta:
model = Client
search_indexes.py
from haystack.indexes import *
from haystack import site
from clients.models import Client
class ClientIndex(RealTimeSearchIndex):
text = CharField(document=True, use_template=True)
wants_to_rent = BooleanField(model_attr='wants_to_rent')
rental_space_from = CharField(model_attr='rental_space_from')
rental_space_until = CharField(model_attr='rental_space_until')
rental_price_from = CharField(model_attr='rental_space_from')
rental_price_until = CharField(model_attr='rental_space_until')
wants_to_buy = BooleanField(model_attr='wants_to_buy')
buying_space_from = CharField(model_attr='buying_space_from')
buying_space_until = CharField(model_attr='buying_space_until')
def prepare_rental_space_from(self, obj):
return '%08d' % obj.rental_space_from
def prepare_rental_space_until(self, obj):
return '%08d' % obj.rental_space_until
def prepare_rental_price_from(self, obj):
return '%08d' % obj.rental_price_from
def prepare_rental_price_until(self, obj):
return '%08d' % obj.rental_price_until
site.register(Client, ClientIndex)
and search_form.py
from django import forms
from haystack.forms import SearchForm
from haystack.query import SearchQuerySet
from django.utils.translation import ugettext as _
class ClientSearchForm(SearchForm):
"""start_date = forms.DateField(required=False)
end_date = forms.DateField(required=False)"""
wants_to_rent = forms.BooleanField(required=False)
rental_space_from = forms.IntegerField(label=_('STRING_SPACE_FROM'),required=False)
rental_space_until = forms.IntegerField(label=_('STRING_SPACE_UNTIL'),required=False)
rental_price_from = forms.IntegerField(label=_('STRING_PRICE_FROM'),required=False)
rental_price_until = forms.IntegerField(label=_('STRING_PRICE_UNTIL'),required=False)
wants_to_buy = forms.BooleanField(label=_('STRING_WANTS_TO_BUY'),required=False)
buying_space_from = forms.IntegerField(label=_('STRING_SPACE_FROM'),required=False)
buying_space_until = forms.IntegerField(label=_('STRING_SPACE_UNTIL'),required=False)
buying_price_from = forms.IntegerField(label=_('STRING_PRICE_FROM'),required=False)
buying_price_until = forms.IntegerField(label=_('STRING_PRICE_UNTIL'),required=False)
def search(self):
# First, store the SearchQuerySet received from other processing.
sqs = super(ClientSearchForm, self).search()
# Check to see if a start_date was chosen.
"""
if self.cleaned_data['start_date']:
sqs = sqs.filter(pub_date__gte=self.cleaned_data['start_date'])
# Check to see if an end_date was chosen.
if self.cleaned_data['end_date']:
sqs = sqs.filter(pub_date__lte=self.cleaned_data['end_date'])
"""
if self.cleaned_data['wants_to_rent']:
sqs = sqs.filter(wants_to_rent=True)
if self.cleaned_data['rental_space_from']:
sqs = sqs.filter(rental_space_from__gte=self.cleaned_data['rental_space_from'])
if self.cleaned_data['rental_space_until']:
开发者_运维百科 sqs = sqs.filter(rental_space_until__lt=self.cleaned_data['rental_space_until'])
if self.cleaned_data['rental_price_from']:
sqs = sqs.filter(rental_price_from__gte=self.cleaned_data['rental_price_from'])
if self.cleaned_data['rental_price_until']:
sqs = sqs.filter(rental_price_until__lte=self.cleaned_data['rental_price_until'])
if self.cleaned_data['wants_to_buy']:
sqs = sqs.filter(wants_to_buy=True)
if self.cleaned_data['buying_space_from']:
sqs = sqs.filter(buying_space_from__gt=1)
if self.cleaned_data['buying_space_until']:
sqs = sqs.filter(buying_space_until__lt=6)
if self.cleaned_data['buying_price_from']:
sqs = sqs.filter(buying_price_from__gte=self.cleaned_data['buying_price_from'])
if self.cleaned_data['buying_price_until']:
sqs = sqs.filter(buying_price_until__lte=self.cleaned_data['buying_price_until'])
return sqs
I have tried everything - zero padding the integers, reseting my app a gazillion times and I still cannot get any luck! The fields ignored are buying_place_from/until buying_space_from/until and the same goes for rental fields - NOTHING seems to affect them, if any filter is used - there are 0 results... thank you in advice!
I don't have a real answer, but here's how I would look for it:
Try logging/printing the query you're actually building here (sqs just before the end of the search method). it might give you clues as to what is wrong.
Try running the same kind of query (same set of filters) in the shell. what results do you get?
Why are you using CharField
for the ClientIndex
when you can use IntegerField
there?
Also if you zero-pad the integers saved in the CharField
, make sure that you zero-pad the searched value too.
精彩评论