Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 915
Pompeyo Avatar asked Nov 19 '13 20:11

Pompeyo


2 Answers

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?

like image 128
edyssy Avatar answered Sep 21 '22 13:09

edyssy


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
like image 1
DylannCordel Avatar answered Sep 24 '22 13:09

DylannCordel