2013-11-15 133 views
8

我正在嘗試使用Django Haystack進行搜索,然後在檢索結果時我需要將這些結果傳遞給我的Django Rest Framework序列化程序。Django Haystack結果到Django Rest框架序列化程序

Django Rest Framework serializers.ModelSerializer要求發送對象的查詢集以使序列化程序能夠序列化這些對象及其數據庫字段。

當我創建我的API視圖並使用搜索來獲取結果時,haystack返回一個searchqueryset。

我怎麼能得到這個searchqueryset成一個Django的queryset沒有做這樣的事情:

article_queryset = Article.objects.filter(id__in=[i.object for i in searchqueryset]) 

正如你能想象,有時搜索可以返回超過1000個的搜索結果,這意味着以上將是非常低效的。

現在,Django rest框架允許我分頁返回對象。我在每個頁面上分配30個對象。我怎麼可能用我的Haystack searchqueryset做同樣的事情?

任何有關如何使用Haystack和Django Rest Framework的建議或想法都會很棒。其他人如何做類似的事情的例子也會很酷:)

+0

您使用的是什麼搜索後端?如果您使用elasticsearch,那麼您可能需要採取額外步驟,因爲在elasticsearch搜索結果中已經以_source字段以json形式返回。 –

回答

8

您可以使用Haystack的SearchView(而不是DRF視圖),它公開頁面對象的分頁。然後你可以將它傳遞給你的序列化器。

E.G.一段時間以來,我一直在研究需要當前HTML頁面上呈現結果的json對象的東西,所以我編寫了一個過濾器標記來完成此操作(我們將FacetedSearchView用於UI,將DRF用於更通用的RESTful API) 。所謂的像這樣的模板:

var articlesJson = {{ page.object_list|article_jsonify }} 

實際的過濾器標籤:

import collections 
from django.template import Library 
from django.utils.safestring import mark_safe 
from rest_framework.renderers import JSONRenderer 

register = Library() 


def article_jsonify(object): 
    if isinstance(object, collections.Iterable): 
     many = True 
     ids = [obj.object.id for obj in object] 
    else: 
     many = False 
     ids = [object.id] 

    articles = Article.objects.filter(pk__in=ids) 
    serializer = ArticleSerializer(articles, many=many) 
    content = JSONRenderer().render(serializer.data) 
    return mark_safe(content) 

register.filter('article_jsonify', article_jsonify) 

你也可以寫一個視圖從generics.ListAPIView繼承和覆蓋get_queryset方法,在那裏你會通過將請求的查詢參數設置爲SearchQuerySet,然後使用串化器輸出它。這裏更多的信息:

http://www.django-rest-framework.org/api-guide/filtering

當然,你可能無法使用ModelSerializer這樣,除非你做一些像你提到的。然而DRF對使用像這樣一個查詢集的分頁程序的例子:

http://www.django-rest-framework.org/api-guide/pagination#paginating-querysets

UPDATE 我結束了最後使用使用草堆SearchQuerySet作爲查詢集一個DRF視圖,然後將它傳遞給Paginator。這裏有一個簡化的例子(我相信它可以簡化一些),但我希望它能幫助別人開始。

class ArticleList(ListCreateAPIView): 

    """ 
    List, Create files 
    """ 
    model = Article 

    def get(self, request, *args, **kwargs): 
     # simplified filtering of an SQS 
     q = request.get('q', '') 
     sqs = SearchQuerySet().filter(content=Clean(q)) 
     paginator = Paginator(sqs, 20) 

     page = request.QUERY_PARAMS.get('page') 
     try: 
      articles = paginator.page(page) 
     except PageNotAnInteger: 
      # If page is not an integer, deliver first page 
      articles = paginator.page(1) 
     except PageNotAnInteger: 
      # If page is out of range, deliver last page 
      articles = paginator.page(paginator.num_pages) 

     serializer_context = {'request': request} 
     serializer = PaginatedArticleSerializer(articles, context=serializer_context) 

     return Response(serializer.data) 

class ArticleSerializer(serializers.ModelSerializer): 

    """ 
    Base Article Serializer 
    """ 

    class Meta: 
     model = Article 

class PaginatedArticleSerializer(pagination.PaginationSerializer): 

    """ 
    Serializes page objects of article querysets. 
    """ 
    start_index = serializers.SerializerMethodField('get_start_index') 
    end_index = serializers.SerializerMethodField('get_end_index') 
    num_pages = serializers.Field(source='paginator.num_pages') 

    class Meta: 
     object_serializer_class = ArticleSerializer 

    def get_start_index(self, page): 
     return page.start_index() 

    def get_end_index(self, page): 
     return page.end_index() 

    def get_curr_page(self, page): 
     return page.number 
+0

我不明白這段代碼如何使用需要Article模型實例的序列化程序來序列化Haystacks SearchResults的實例。我試圖爲一個簡單的api端點實現一個簡單版本,該端點將輸出包含與搜索結果關聯的序列化模型實例的JSON。 –

+0

SearchResult和SearchQuerySet在Django的Model和Queryset類之後建模(沒有雙關語意圖),因此它們具有相似的行爲和接口。我相信它只是爲我工作,我會看看,讓你知道如果我不得不做任何特殊的序列化器。 – mynameistechno

相關問題