How to index a foreign key CharField using Haystack/Whoosh with Django?
Asked Answered
A

2

6

Using prepare_FOO(self, object) method, I'm trying to index a ForeignKey to get the name attribute of my tags (travel, family, ...)

This is my model

class Blog(models.Model):
    title = models.CharField(max_length=500)
    description = models.TextField(blank=True, null=True)
    tag = models.ForeignKey(Tag)
    #...

And in my search_index.py, that's what I have:

class BlogIndex(indexes.SearchIndex, indexes.Indexable):

    text = indexes.CharField(document=True, use_template=True)
    title = indexes.CharField(model_attr='title')
    description = indexes.CharField(model_attr='description')

    tag_name = indexes.CharField()
    def get_model(self):
        return Blog

    def prepare_tag_name(self, obj):
        return obj.tag.name

    def index_queryset(self, using=None):
        return self.get_model().objects.all().select_related('blog__tag')

... And my blog_text:

{{ object.title }}
{{ object.description }}

Any help would be appreciated, thank you!

Akeyla answered 19/11, 2013 at 20:41 Comment(4)
why your get_model returns Convention instead of Blog?Thrown
Sorry, it's a typo. I just update my question.Akeyla
what exactly isn't working? your code looks okay nowThrown
It just doesn't return any value, when I try to search for tag nameAkeyla
F
5

You only need to add the following in your blog_text file blog_text and rebuild your index. and it works!

{{ object.title }}
{{ object.description }}
{{ object.tag.name }}

you don't need this in your class BlogIndex

tag_name = indexes.CharField()
def prepare_tag_name(self, obj):
    return obj.tag.name

similar answer is here Search over multiple fields a nice explanation is here haystack multiple field search In your index you should define one field with document=True, which is the document haystack will search on. By convention this field is named text. You add extra fields if you plan to do filtering or ordering on their values.

So essentially, the fields you include in your Index class are mainly for sorting or filtering. the search fields are defined in blog_text file.

Another solution is here which is more complicated. haystack - how you display data from multiple models with ForeignKeys?

Fifteen answered 5/1, 2014 at 17:22 Comment(0)
B
1

This is a very old question but given answer does not really answer to the problem (even this is a correct answer anyway) Pompeyo, I think haystack require (required ?) a "model_attr" arg. You should defined your tag_name like this :

tag_name = indexes.CharField(model_attr='tag')

And your prepare_foo method :

def prepare_tag_name(self, obj):
    return '' if not obj.tag else obj.tag.name
Bernardabernardi answered 26/2, 2015 at 15:11 Comment(2)
Isn't this wrong? If you define a prepare_foo method the model_attr will be ignored imho.Adumbral
Yes, the model_attr is ignored, (in my exemple, it is not set with "tag_name" but with "tag" : any field of the model). But I think that it is (falsly) required to avoid some problems. Maybe not in recent versions. i'll test it.Bernardabernardi

© 2022 - 2024 — McMap. All rights reserved.