Reputation: 1381
I would like to add a field from a second model to a django-haystack query. I have two models that have the following structure:
class Product(models.Model):
created_date = models.DateField(auto_now_add=True)
name = models.CharField(max_length=254)
summary = models.CharField(null=True, blank=True, max_length=255)
....
class Color(models.Model):
product_color = models.CharField(max_length=256, blank=True, null=True)
created_date = models.DateField(auto_now_add=True)
slug = models.SlugField(max_length=254)
product = models.ForeignKey('Product')
I have the following search_index.py:
from django.utils import timezone
from haystack import indexes
from .models import Product
from .models import Color
class ProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
return Product
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(
created_date__lte=timezone.now())
How can I add the Color
model's product_color
to the search index so that if someone includes a partial portion of a product_color
in a search query it will return a Product
that has a ForeignKey relationship to the color?
Upvotes: 1
Views: 332
Reputation: 39659
Use MultiValueField
which will store all colors associated with product:
product_colors = indexes.MultiValueField()
Prepare it:
def prepare_product_colors(self, obj):
return [o.product_color for o in obj.color_set.all()]
And use that field directly to filter by product color. Or If you don't want to use search on specific field rather do an auto query then append the product colors to the final indexed text:
def prepare(self, obj):
prepared_data = super(SlateUpIndex, self).prepare(obj)
prepared_data['text'] += ' '.join(self.prepare_product_colors(obj))
return prepared_data
Instead of doing all the above things just add the colors in the template search/indexes/{app_label}/{model_name}_{field_name}.txt
:
{% for color in object.color_set.all %}
{{ color.product_color }}
{% endfor %}
Upvotes: 2
Reputation: 2513
Do products have multiple colors? If not, i'd FK to 'Color' from the 'Product' model.
As-is, you can add a MultiValue Field to your index and prepare the values using a 'prepare_foo' function that is a built-in helper a-la 'clean_foo' in django forms.
See the docs for more info: SearchIndex Api
For example:
colors = indexes.MultValueField()
def prepare_colors(self, obj):
return [color.product_color for color in obj.color_set.all()]
Upvotes: 0