I'm pretty new to search implementation, bear with me while I'm learning!
So my pet project is a recipe site and each recipe can have n steps. the model looks something like:
class Recipe(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
hotness = models.ForeignKey(Hotness)
recipe_diet = models.ManyToManyField(DietType)
ingredients = models.ManyToManyField(Ingredient, through="RecipeIngredient")
class DietType(models.Model):
diet_type = models.CharField(max_length=50)
description = models.TextField(null=True, blank=True)
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe)
ingredient = models.ForeignKey(Ingredient)
quantifier = models.ForeignKey(Quantifier)
quantity = models.FloatField()
class RecipeSteps(models.Model):
step_number = models.IntegerField()
description = models.TextField()
recipe = models.ForeignKey(Recipe)
(shortened for brevity)
I want to index all of it: Recipe, RecipeIngredient, DietType and Steps... The DietType and RecipeIngredient seem to be working fine, but the Steps are not. I assume this has to do with the usage of 'RelatedSearchQuerySet' ?
Here is my search_indexes.py:
from haystack import indexes
from recipes.models import Recipe
class RecipeIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
ingredients = indexes.MultiValueField(indexed=True, stored=True)
description = indexes.CharField(model_attr='description')
hotness = indexes.CharField(model_attr='hotness')
diet_type = indexes.MultiValueField(indexed=True, stored=True)
recipesteps = indexes.MultiValueField(indexed=True, stored=True)
def prepare_steps(self, object):
return [step.description for step in object.recipesteps.all()]
def get_model(self):
return Recipe
def load_all_queryset(self):
# Pull all objects related to the Note in search results.
return Recipe.objects.all().select_related()
Here is the template recipe_text.txt:
{{ object.title }}
{{ object.cuisine }}
{% for ingr in object.ingredients.all %}
{{ ingr.title }}
{% endfor %}
{{ object.description }}
{% for dt in object.recipe_diet.all %}
{{ dt.diet_type }}
{% endfor %}
{{ object.user }}
{{ object.hotness }}
{% for step in object.recipesteps.all %}
{{ step.description }}
{% endfor %}
{{ object.body }}
I can search ingredients, title, description, diet type - everything works, except the RecipeSteps.
Finally, I'm making queries through the shell only at the moment:
#producing results:
sq = SearchQuerySet().filter(content='onion') #ingredient
sq = SearchQuerySet().filter(content='bolognese') #title
sq = SearchQuerySet().filter(content='bologna') #description
#not producing any results:
sq = SearchQuerySet().filter(content='chop') #step
sq = RelatedSearchQuerySet().filter(content='chop').load_all() #assuming this does the expanded search
Any idea?
Haystack is building a search engine for the inventory of local retailers, allowing you to search for a product and see the closest stores carrying it.
Haystack is a Python framework for natural language processing (NLP) that focuses on semantic search and question answering (QA). Haystack enables the users to ask a question in natural language, and receive an informative answer from a large collection of documents — all within seconds.
Haystack provides modular search for Django. It features a unified, familiar API that allows you to plug in different search backends (such as Solr, Elasticsearch, Whoosh, Xapian, etc.) without having to modify your code.
I have identified two issues:
The name prepare_steps
in your RecipeIndex
is wrong it should be prepare_{field_name}
so change it to prepare_recipesteps
You are trying to access related steps object.recipesteps.all
objects recipe_text.txt
in a wrong way, it should be object.recipesteps_set.all
. Or keep using recipesteps
but add this as a related_name in RecipeSteps
model for ForeignKey
Recipe e.g.
class RecipeSteps(models.Model):
# //
recipe = models.ForeignKey(Recipe, related_name='recipesteps')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With