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
我已经尝试了一切 - 用零填充整数,重置我的应用程序无数次,但我仍然无法获得任何运气!忽略的字段是 buy_place_from/until buy_space_from/until ,租赁字段也是如此 - 如果使用任何过滤器,似乎不会影响它们 - 有 0 个结果...谢谢您的建议!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我没有真正的答案,但这是我寻找它的方法:
尝试记录/打印您实际在此处构建的查询(在搜索方法结束之前的 sqs )。它可能会为您提供有关问题所在的线索。
尝试在 shell 中运行相同类型的查询(同一组过滤器)。你得到什么结果?
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?
当您可以在其中使用
IntegerField
时,为什么要在ClientIndex
中使用CharField
呢?此外,如果您对
CharField
中保存的整数进行零填充,请确保也对搜索值进行零填充。Why are you using
CharField
for theClientIndex
when you can useIntegerField
there?Also if you zero-pad the integers saved in the
CharField
, make sure that you zero-pad the searched value too.