高级搜索特定的Django模型

时间:2009-06-09 23:00:38

标签: django django-models

我知道全文搜索应用程序,如Django Solr和solango等。

我正在寻找的内容更类似于对房地产网站的高级搜索。 例如,他们可以选择类似于www.viewr.com高级搜索的位置,价格等。

到目前为止,我所做的是在模型自定义管理器下:

def advanced_search(self, district, location, type, facilities, features, not_permitted):
        q_objects = []
        l_objects = []
        t_objects = []
        fc_objects = []
        ft_objects = []
        np_objects = []

        if district:
            if location:
                for loc in location:
                    l_objects.append(Q(location__exact=loc))
            else:
                l_objects.append(Q(location__district=district))


        if type:    
            for ty in type:
                t_objects.append(Q(listing_type__exact=ty))

        if facilities:    
            for fc in facilities:
                fc_objects.append(Q(property_facilities__exact=fc))

        if features:
            for ft in features:
                ft_objects.append(Q(property_features__exact=ft))
                ft_objects.append(Q(community_features__exact=ft))

        if not_permitted:    
            for np in not_permitted:
                np_objects.append(Q(not_permitted__exact=np))                              

        # Start with a bare QuerySet
        qs = self.get_query_set()

        if location:
            qs = qs.filter(reduce(operator.or_, l_objects))
        if type:
            qs = qs.filter(reduce(operator.or_, t_objects))
        if facilities:
            qs = qs.filter(reduce(operator.or_, fc_objects))
        if features:
            qs = qs.filter(reduce(operator.or_, ft_objects))
        if not_permitted:
            qs = qs.filter(reduce(operator.or_, np_objects))
        # Use operator's or_ to string together all of your Q objects.
        return qs

现在我没有得到非常可预测的结果。有什么我可能做错了吗?有没有更好的方法来进行各种OR搜索/连接?

4 个答案:

答案 0 :(得分:2)

只是一些想法。

在这种情况下,使用kwargs解包为过滤方法提供参数非常有用。 这样的事情可以使代码更简单:

kwargs = {'not_permitted':np,'property_features': ft}
return qs.filter(**kwargs)

也许您应该在admin中查看django的过滤代码。在django中,管理员参数如not_permitted__exact通过GET传递。然后,经过一些过滤后,整个GET字典可以作为解包的kwargs参数传递给filter方法。当你有很多过滤选项时,这会让事情变得非常简单。

答案 1 :(得分:2)

我最接近这种情况的是雅各布的这篇文章:

http://www.djangosnippets.org/snippets/32/

我所做的是:

def advanced_search(self, form):
        # It's easier to store a dict of the possible lookups we want, where
        # the values are the keyword arguments for the actual query.
        qdict = {'district': 'location__district',
          'location': 'location',
          'property_type': 'listing_type',
          'max_price': 'price__lte',
          'property_features': 'property_features',
          'community_features': 'community_features',
        }

        # Then we can do this all in one step instead of needing to call
        # 'filter' and deal with intermediate data structures.
        q_objs = [Q(**{qdict[k]: form.cleaned_data[k]}) for k in qdict.keys() if form.cleaned_data.get(k, None)]        
        search_results = RealEstateListing.objects.select_related().filter(*q_objs)
        return search_results

当我通过单一选择时,它工作正常,但是当通过多个选择时,它会扼杀并说:

OperationalError:子查询返回多行

答案 2 :(得分:1)

http://code.google.com/p/djapian/可以为您选择的字段编制索引,并允许您通过组合,布尔逻辑等构建复杂的搜索。

答案 3 :(得分:0)

我知道这篇文章有些陈旧,但是我碰到了这一点,我认为在寻求简单快速的解决方案时其他人可能会这么做

not