Reputation: 169
I have these two models:
class Shop(CustomBaseModel):
username = models.CharField(max_length=200)
bio = models.CharField(max_length=200)
class Item(CustomBaseModel):
shop = models.ForeignKey(Shop)
tags = models.TextField()
And I have this index in search_indexes.py:
class ItemIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
tags = indexes.CharField(model_attr='tags')
And this item_text.txt file:
{{ object.tags}}
This is my view:
def search(request):
form = ItemSearchForm(request.GET)
results = form.search()
return render(request, 'search/search.html', {
'items': results
})
This is my form:
class ItemSearchForm(SearchForm):
def search(self):
sqs = super(ItemSearchForm, self).search().models(Item, Shop)
return sqs
This is the template:
{% if items|length > 0 %}
<h1>Items</h1>
{% for item in items %}
<p>
{{ item.tags }}
</p>
{% endfor %}
{% endif %}
This is searching from tags and working fine. But how can I display all items that belong to a shop if someone includes a username or bio of that shop?
Upvotes: 2
Views: 1211
Reputation: 10553
When using Haystack and you got the result query set you have a list of objects, the fields of this objects depends on what you've wrote in:
templates/search/indexes/project_name/modelName_text.txt
But there is allways a field that can help you here, the field object
If I understand your question you want to know:
I'll show you how to do it in command line, you can apply this code to your view/template:
from haystack.query import SearchQuerySet
# First we make a search to get some shops
# assuming you defined username field in search_indexes.py for Shop object
shop_list = SearchQuerySet().filter(username='something')
# or
shop_list = SearchQuerySet().filter(content='shop_username')
# Now (let's supose there is at least 1 shop) you can get the items like:
shop_list[0].object # This returns the shop object, so you can do
shop_list[0].object.item_set.all() # This returns all items belonging to this shop
In your template you could try:
{{ object.object.item_set.all }} # This return a list of items belonging to shop
<ul>
{% for item in object.object.item_set.all %}
<li>{{item}}</li>
{% endfor %}
</ul>
This can be confused because you called object to your variable, but you need to remember that a SearchQuerySet instance allways have this object
field to access the original Django object
I recommend you to check Haystack - SearchQuerySet API
In your template your results are in the variable items
so you can do something like:
# Assumming all the items are shops
{% for shop in items %}
{{shop.object.item_set}} # If the item is a SHop, this return all its items
{% endfor %}
To separate the results, because I supose not all the items are shops, you can separate the results and send the shops in another variable to the template like:
def search(request):
form = ItemSearchForm(request.GET)
results = form.search()
return render(request, 'search/search.html', {
'items': results
'shops': results.model(Shop)
})
So in your template you can do:
{% for shop in shops %}
{{shop.object.item_set}}
{% endfor %}
Okay now it looks you have items in your template... and you want all the items of a shop ?
You said:
But how can I display all items that belong to a shop if someone includes a username or bio of that shop?
So you're using haystack to search for items, but want the results to be shops ?
You could add into your item_text.txt file:
{{ object.tags}}
# If you add this and you look for shop username
# or bio it will return all items of the shop
{{ object.shop.username}}
{{ object.shop.bio}}
# Adding this 2 fields items are indexed with the related shop username and bio
or you can start indexing Shop model too.
Upvotes: 2