使用haystack索引和搜索相关对象

时间:2017-06-26 20:20:44

标签: python django django-models django-haystack whoosh

我对搜索实施很陌生,在我学习的同时忍受我!

所以我的宠物项目是食谱网站,每个食谱都可以有n个步骤。该模型看起来像:

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)

(简称简称)

我想索引所有内容:Recipe,RecipeIngredient,DietType和Steps ... DietType和RecipeIngredient似乎工作正常,但步骤不是。我认为这与使用' RelatedSearchQuerySet'有关。 ?

这是我的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()

这是模板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 }}

我可以搜索成分,标题,描述,饮食类型 - 一切正常,但RecipeSteps除外。

最后,我现在只通过shell进行查询:

#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

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

我发现了两个问题:

  1. prepare_steps中的RecipeIndex名称错误,prepare_{field_name}应该prepare_recipesteps

  2. 您正试图以错误的方式访问相关步骤object.recipesteps.all对象recipe_text.txt,它应该是object.recipesteps_set.all。或继续使用recipesteps,但在RecipeSteps模型ForeignKey模式中将其添加为related_name,例如。

    class RecipeSteps(models.Model):
        # //
        recipe = models.ForeignKey(Recipe, related_name='recipesteps')