Django与Haystack搜索问题
我正在使用Python 2.6,最新的haystack,还有django 1.2 beta版本。我尝试过Woosh和Xapian这两种后端。
我遇到的问题是,无法对整数字段使用__lt(小于)或__gt(大于)过滤器——每次使用这些过滤器时,结果总是没有找到...
我的模型是:
# -*- 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)
还有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
我尝试了所有方法——给整数加零填充,重置我的应用程序无数次,但还是没有任何进展!被忽略的字段是buying_place_from/until和buying_space_from/until,租赁字段也是如此——如果使用了任何过滤器,结果都是0...谢谢你的帮助!
2 个回答
0
你为什么在ClientIndex
那里用CharField
,而不是用IntegerField
呢?
另外,如果你在CharField
中保存的整数是用零填充的,那你在搜索的时候也要确保搜索的值是用零填充的。
0
我没有一个确切的答案,但我可以告诉你我会怎么找答案:
试着在这里记录或打印出你实际构建的查询(在搜索方法结束前的sqs)。这样可能会给你一些线索,帮助你找出问题所在。
试着在命令行中运行相同类型的查询(使用相同的过滤条件)。你得到了什么结果呢?