Django haystack SearchQuerySet to QuerySet

时间:2012-11-30 09:47:27

标签: django solr django-queryset django-haystack

我有一个非常通用的视图/模板来显示给定模型的查询集的内容 我在12个地方使用12个不同的查询集,现在我想在那里集成haystack搜索,但我不能,因为SearchQuerySet与模板中的QuerySet不匹配。

使用正常的查询集我

{%for obj in qs%}
    {{obj.foreign_key.name }}
{%endfor%}

使用SearchQuerySet我需要做

{%for obj in qs%} 
   {{obj.object.foreign_key.name}}
{%endfor%}

这基本上打破了我的通用模板和视图,现在知道查询集的来源。

我想要一种方法让searchqueryset像普通的查询集一样,我知道:

  • 我会失去分数,虽然我会保留命令
  • 我需要做一个load_all()来获取
  • 中的整个对象

有关如何保持模板通用但接受SearchQuerySet或将SearchQuerySet转换为QuerySet的任何提示?

4 个答案:

答案 0 :(得分:7)

我使用了一个简洁的生成器技巧,可以避免向模型中添加object方法,并允许您为Django的QuerySet和Haystack SearchQuerySet使用相同的模板。

诀窍是将SearchQuerySet包装到生成器中。

# In your view...

def queryset_gen(search_qs):
    for item in search_qs:
        yield item.object  # This is the line that gets the model instance out of the Search object

qs = queryset_gen(sqs)

这种方法的优点在于它维护了返回SearchQuerySet的顺序,并节省了计算和内存,因为您不需要创建或存储列表的另一个实例。

答案 1 :(得分:2)

如何在名为object的模型上添加方法,以便查询集的行为类似于SearchQuerySet?例如

class MyModel(models.Model):
    ...
    def object(self):
        return self

答案 2 :(得分:0)

您可以制作如下数组:

q = request.GET['q']
    results = SearchQuerySet().auto_query(q)
    obj = []
    for r in results:
        obj.append(r.object)
    return render_to_response('template.html',
        {'obj': obj )

答案 3 :(得分:0)

对于那些来到这里寻找更一般的治疗SQS的方法,如QS。

我需要Django Rest Framework这样的东西,所以我为sqs创建了以下包装器 - > QS。 它允许处理SQS,就像它是一个对迭代和切片支持有限的查询集一样。

您也可以在迭代生成器函数之前调用load_all。

class SearchQuerySetWrapper(object):
    """
    Decorates a SearchQuerySet object using a generator for efficient iteration
    """
    def __init__(self, qs):
        self.qs = qs

    def count(self):
        return self.qs.count()

    def __iter__(self):
        for result in self.qs:
            yield result.object

    def __getitem__( self, key):
        if isinstance(key, int) and (key >= 0 or key < self.count()):
            # return the object at the specified position
            return self.qs[key].object
        # Pass the slice/range on to the delegate
        return SearchQuerySetWrapper(self.qs[key])
相关问题