基于多个索引字段的Django-Haystack搜索 [英] Django-Haystack Search based on multiple index fields

查看:160
本文介绍了基于多个索引字段的Django-Haystack搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是django-haystack的新手。根据文档和教程,我能够基于文档内容(Database SQLITE)创建搜索应用程序。下一步,我已经更新了HTML模板,以请求更多信息(例如:模型,所需的数据库链接等)。



我不知道该如何处理。在我正在使用的文件下面。我的知识仍然很基础,因此非常感谢您。



谢谢。



search.html

  {%扩展了'base.html'%} 

{%块内容%}


< h2> Doc搜索界面< / h2>

< form method = get action =。>
< table>
< P>选择汽车型号:< / P>
< P>< LABEL ACCESSKEY = 5><输入类型=复选框NAME = CarModel VALUE = A5> A5< LABEL< BR>
< LABEL ACCESSKEY = 8><输入类型=复选框NAME = CarModel VALUE = A8> A8< LABEL> BR>
< LABEL ACCESSKEY = 3><输入类型=复选框NAME = CarModel VALUE = A3> A3< LABEL< / P>

< tr>
< P>键入并单击Enter以进行搜索!< / P>
<输入类型=搜索 id = id_q名称= q占位符=搜索>
< / tr>
< / table>

{%if query%}
< h3>让我们看看我们是否在这里找到了您要查找的文档...< / h3>

{%for page.object_list%}
< p>
< a href = {{result.object.get_absolute_url}}> {{result.object.title}}< / a>
< / p>
{%empty%}
< p>未找到结果。
{%endfor%}

{%如果page.has_previous或page.has_next%}
< div>
{%if page.has_previous%}< a href =?q = {{query}}& amp; page = {{page.previous_page_number}}> {%endif%}& laquo ;上一页{%如果page.has_previous%}< / a> {%endif%}
|
{%if page.has_next%}< a href =?q = {{query}}& amp; page = {{page.next_page_number}}> {%endif%} Next& raquo; {%if page.has_next%}< / a> {%endif%}
< / div>
{%endif%}
{%else%}
{#显示一些要运行的示例查询,也许是查询语法,还有其他内容吗? #}
{%endif%}
< / form>
{%endblock%}

models.py

 从django.db导入模型
从django.contrib.auth.models导入用户
从django.template从django.http导入RequestContext
.http导入HttpResponse

class Document(models.Model):

user_id = models.CharField(max_length = 6,default ='admin ')
pub_date = models.DateTimeField()
title = models.CharField(max_length = 200)
Link = models.URLField()
content = models.TextField()
CarModel = models.TextField()

def get_absolute_url(self):
return self.Link
def __unicode __(self):
return self.title

search_indexes.py

 从haystack导入索引
从test3.models导入文档

类DocumentIndex(indexes.SearchIndex,indexs.Indexable):
文字= indexs.EdgeNgramField(document = True,use_te mplate = True)
content_auto = indexes.EdgeNgramField(model_attr ='content')
CarModel = indexes.EdgeNgramField(model_attr ='CarModel')
def get_model(self):
return Document
def index_queryset(self,using = None):
在更新模型的整个索引时使用。通常是为了避免某些结果显示,当管理员不希望
返回self.get_model()。objects

此其他文章之后使用django在模板中使用全局搜索栏进行干草堆搜索我已经更新了以下文件



urls.py


django.conf.urls中的

  url从test3.views导入URL 
导入MySearchView


#urls。 py

urlpatterns = [url(r'^ / search /?$',MySearchView.as_view(),name ='My_search_view'),]

views.py

 从haystack.forms导入HighlightedSearchForm 
从haystack.query导入SearchQuerySet
从haystack.generic_views导入SearchView
从haystack.views导入search_view_factory

类MySearchView(SearchView) :
我的自定义搜索视图。
def search_posts(request):
post_type = str(request.GET.get('CarModel'))。lower()
print( str(request.GET.get('CarModel'))。lower())
sqs = SearchQuerySet()。filter(CarModel__contains = post_type)
clean_query = sqs.query.clean(post_type)
结果= sqs.filter(内容=清洁查询)
视图= search_view_factory(
view_class = SearchView,
template ='search / search.html',
searchqueryset = result,
form_class = HighlightedSearchForm

返回视图(请求)

但是,我仍然没有使其工作...搜索结果仍未按模型字段过滤。我想我必须添加额外的代码,但是我不知道在哪里...

解决方案

我将尝试对此做出回应。这就是我的工作方式:



yourapp / urls.py



  url(r'^ search / $',views.search_notes,name ='search_notes'),

yourapp / views.py 中,导入NotesSearchForm(在下方)并在搜索时调用它:



<$从$ .forms导入p $ p> 导入NotesSearchForm

def search_notes(request):
form = NotesSearchForm(request.GET)
notes = form.search ()
return render_to_response('notes / index.html',{'notes':notes,'form':form})

context = {'latest_notes_list':Latest_notes_list}
return render(request,'notes / index.html',context)

然后在您的< Strong> yourapp / forms.py 是发生魔术的地方:

  from haystack.forms import SearchForm 

类NotesSearchForm(SearchForm):

#首先,在您的情况下,添加表单字段BooleanFields。
sports = forms.BooleanField()
小说= forms.BooleanField()
non_fiction = forms.BooleanField()


def search(self) :
#在这里,我们存储从其他处理收到的SearchQuerySet。
sqs = super(NotesSearchForm,self).search()

如果不是self.is_valid():
return self.no_query_found()

#然后在搜索返回时过滤结果

如果self.cleaned_data ['sports']:
sqs = sqs.filter(genre ='sports')
如果self .cleaned_data ['fiction']:
sqs = sqs.filter(genre ='fiction')
if self.cleaned_data ['non_fiction']:
sqs = sqs.filter(genre = 'non_fiction')

return sqs

def no_query_found(self):
#这是为了使所有结果都显示为是否未选择或搜索任何内容(可选)
return self.searchqueryset.all()

请注意,这里我放了'genre'作为模型中字段的名称。此字段还需要显示在您的 search_indexes.py 中,例如:

  genre = indexs .CharField(model_attr ='genre')

最后,让我向您展示 yourapp / template / notes / index.html

 <!-在这里形成表格-> 
{{form}}

<!-在这里搜索结果->
{用于注释的百分比%}

{{note.object.title}}
{{notes.object.body | linebreaks}}>

{%endfor%}

希望它对您有用!请告诉我您卡住。


I am quite a newbbie with django-haystack. Following documentation and tutorials I was able to create a search App based on document content (DataBase SQLITE). As next step, I have updated my HTML template to request for more info (e.g.: Model, desired DB link, etc.)

I do not know how to approach this. Below the files I am using. My knowledge is still quite basic, so any help would be very much appreciated.

Thanks.

search.html

{% extends 'base.html' %}

{% block content %}


    <h2> Doc Search Interface</h2>

    <form method="get" action=".">
        <table>
            <P>Select Car Model:</P>
            <P><LABEL ACCESSKEY=5><INPUT TYPE=checkbox NAME="CarModel" VALUE="A5"> A5</LABEL><BR>
            <LABEL ACCESSKEY=8><INPUT TYPE=checkbox NAME="CarModel" VALUE="A8"> A8</LABEL><BR>
            <LABEL ACCESSKEY=3><INPUT TYPE=checkbox NAME="CarModel" VALUE="A3"> A3</LABEL></P> 

            <tr>
            <P>Type and click enter for Search!</P>
                <input type="search" id="id_q" name="q" placeholder="Search" >
            </tr>
        </table>

        {% if query %}
            <h3>Let´s see if we have got here the document you were looking for...</h3>

            {% for result in page.object_list %}
                <p>
                    <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
                </p>
            {% empty %}
                <p>No results found.</p>
            {% endfor %}

            {% if page.has_previous or page.has_next %}
                <div>
                    {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}
                    |
                    {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
                </div>
            {% endif %}
        {% else %}
            {# Show some example queries to run, maybe query syntax, something else? #}
        {% endif %}
    </form>
{% endblock %}

models.py

from django.db import models
from django.contrib.auth.models import User
from django.template import RequestContext
from django.http import HttpResponse

class Document(models.Model):

user_id = models.CharField(max_length=6, default='admin')
pub_date = models.DateTimeField()
title = models.CharField(max_length=200)
Link= models.URLField()
content = models.TextField()
CarModel= models.TextField()

    def get_absolute_url(self):
        return self.Link
    def __unicode__(self):
        return self.title

search_indexes.py

from haystack import indexes
from test3.models import Document

class DocumentIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True, use_template=True)
    content_auto=indexes.EdgeNgramField(model_attr='content')
    CarModel=indexes.EdgeNgramField(model_attr='CarModel')
    def get_model(self):
        return Document        
    def index_queryset(self, using=None):
        """Used when the entire index for model is updated. Typically to avoid some results showing when admin do not want to""" 
        return self.get_model().objects

Following this other post Using django haystack search with global search bar in template I have updated the following files

urls.py

from django.conf.urls import url
from test3.views import MySearchView


# urls.py

urlpatterns =  [url(r'^/search/?$', MySearchView.as_view(), name='My_search_view'),]

views.py

from haystack.forms import HighlightedSearchForm
from haystack.query import SearchQuerySet
from haystack.generic_views import SearchView
from haystack.views import search_view_factory

class MySearchView(SearchView):
    """My custom search view."""
    def search_posts(request):
        post_type = str(request.GET.get('CarModel')).lower()
        print (str(request.GET.get('CarModel')).lower())
        sqs = SearchQuerySet().filter(CarModel__contains=post_type)
        clean_query = sqs.query.clean(post_type)
        result = sqs.filter(content=clean_query)
        view = search_view_factory(
            view_class=SearchView,
            template='search/search.html',
            searchqueryset=result,
            form_class=HighlightedSearchForm
            )
        return view(request)

However, I still did not make it work...Search results are still not filtered by 'Model' field. I guess I have to add extra code, but I do not know where...

解决方案

I'll try respond to this. This is how I got it working:

In yourapp/urls.py

url(r'^search/$', views.search_notes, name='search_notes'),

In yourapp/views.py import your NotesSearchForm (further below) and call that on search:

from .forms import NotesSearchForm

def search_notes(request):
   form = NotesSearchForm(request.GET)
   notes = form.search()
   return render_to_response('notes/index.html', {'notes': notes, 'form': form})

   context = { 'latest_notes_list': latest_notes_list}
   return render(request, 'notes/index.html', context)

Then in your yourapp/forms.py is where the magic happens:

from haystack.forms import SearchForm

class NotesSearchForm(SearchForm):

   # First we add the form fields, in your case BooleanFields.
   sports = forms.BooleanField()
   fiction = forms.BooleanField()
   non_fiction = forms.BooleanField()


   def search(self):
      # Here we store the SearchQuerySet received from other processing.
      sqs = super(NotesSearchForm, self).search()

      if not self.is_valid():
         return self.no_query_found()

      # Then filter your results when the search come back

      if self.cleaned_data['sports']:
         sqs = sqs.filter(genre='sports')
      if self.cleaned_data['fiction']:
         sqs = sqs.filter(genre='fiction')
      if self.cleaned_data['non_fiction']:
         sqs = sqs.filter(genre='non_fiction')

      return sqs   

   def no_query_found(self):
      # This we add to make all results show if nothing is selected or searched for (optional)
      return self.searchqueryset.all()

Note that here I put 'genre' as what the field is named in your model. This field also need to be present in your search_indexes.py, like this:

genre = indexes.CharField(model_attr='genre')

Finally, let me show you the yourapp/templates/notes/index.html:

<!-- Form here -->
{{ form }}

<!-- Search results here -->
{% for note in notes %}

   {{ note.object.title }}
   {{ notes.object.body|linebreaks }}">

{% endfor %}

Hope it works for you! Let me know if you get stuck.

这篇关于基于多个索引字段的Django-Haystack搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆