I was reading the docs and some questions around here and couldn't understand how can I return a query that has fields indexed in two different classes. Let me put the code below:
Here I have the classes:
class T031003Index(RealTimeSearchIndex):
text = CharField(document=True, use_template=True)
C003INST = IntegerField(model_attr='C003INST')
C003CHCD = CharField(model_attr='C003CHCD')
C003MTR = CharField(model_attr='C003MTR')
C003RZSC = CharField(model_attr='C003RZSC')
def index_queryset(self):
return T031003.objects.all()
def prepare(self, obj):
self.prepared_data = super(T031003Index, self).prepare(obj)
self.prepared_data['text'] = obj.C003CHCD
return self.prepared_data
site.register(T031003, T031003Index)
And the second one:
class T031002Index(RealTimeSearchIndex):
text = CharField(document=True, use_template=True)
C002USER = CharField(model_attr='C002USER')
def index_queryset(self):
return T031002.objects.all()
def prepare(self, obj):
self.prepared_data = super(T031002Index, self).prepare(obj)
self.prepared_data['text'] = obj.C002USER
return self.prepared_data
site.register(T031002, T031002Index)
And I have two template indexes for each of them:
T031003_text:
{{ object.C003INST }}
{{ object.C003CHCD }}
{{ object.C003MTR }}
{{ object.C003RZSC }}
T031002_text:
{{ object.C002USER }}
{{ object.C002INST }}
My template code:
{% if page.object_list %}
{% for object in page.object_list %}
<br>
<li><font class="font">
{{ object.C003RZSC }}, {{ object.C003INST }}, {{ object.C003CHCD }}, {{ object.C003MTR }}, {{ object.C002USER }}
</li>
{% endfor %}
My view:
def search(req):
return SearchView(template='search.html')(req)
If I type in the search box a value from a field, let's say, that belongs to class T031002Index (like user = "vane"), it gives me the result:
"None, None, None, None, vane"
And, if I type a value from a field in class T031003Index, it gives me the result:
"pencil, 1, school material, general, None"
I have between these two classes in models.py a Foreign Key field, which is C002INST.
Could you guys give me an explanation? It seems easy, but I can't figure it out by myself.
Thanks in advance!
So, after a little help from close friends and a lot of research, I could find the solution.
1)I made an upgrade from Haystack 1.2.6 to Haystack 2.0.0
2)In my view, I changed the code to use AutoQuery and SearchQuerySet. It let's you use more that one word to search content and let's you filter results.
Here's the view:
def search(request):
sqs = SearchQuerySet().filter(content=AutoQuery(request.GET['q']))
return render_to_response('search.html', {'sqs': sqs,})
4) Now, in "search_indexes.py", I changed the code to follow 2.0.0 version of Haystack and took off the "model_attr" from the foreign key (T031002Index, C002INST field).
Here's the code:
class T031003Index(RealTimeSearchIndex,Indexable):
text = CharField(document=True, use_template=True)
C003INST = IntegerField(model_attr='C003INST')
C003CHCD = CharField(model_attr='C003CHCD')
C003MTR = CharField(model_attr='C003MTR')
C003RZSC = CharField(model_attr='C003RZSC')
def index_queryset(self):
return T031003.objects.all()
def get_model(self):
return T031003
class T031002Index(RealTimeSearchIndex,Indexable):
text = CharField(document=True, use_template=True)
C002INST = CharField()
C002USER = CharField(model_attr='C002USER')
def index_queryset(self):
return T031002.objects.all()
def get_model(self):
return T031002
But even with all these changes, Haystack would iterate over the two indexes and would return null results. This is wrong and also would lead the user to confusion. So, I changed the template to show me the fields only when they have results which are not null:
{% if page.object_list %}
{% for result in page.object_list %}
{% if result.object.C003MTR%}
<li><b>Matrícula:</b> {{ result.object.C003MTR }}</li>
<li><b>CPF/CNPJ:</b> {{ result.object.C003CHCD }}</li>
{% endif %}
{% if result.object.C002INST %}
<li><b>ID Instituição:</b> {{ result.object.C002INST }}</li>
<li><b>Usuário:</b> {{ result.object.C002USER }}</li>
{% endif %}
{%endfor%}
The "if" will do the trick to test if the field has null results.
Hope it helps other developers using Haystack with Django.