Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

search functionality on multi-language django site

Tags:

I'm building a multi-language Django site, and I'm using django-transmeta for my model data translations. Now I'm wondering if there is a Django search app that works with multi-language models. I've played with Haystack and it works fine for single-language sites, but I can't get it to work with transmeta's metaclasses...

Does anybody have any experience with this? Any pointers would be appreciated!

cheers,

martin

like image 422
Hoff Avatar asked Oct 07 '09 12:10

Hoff


People also ask

How to make multi language website django?

(1) You can keep two separate copies of the site as different Django apps and simply have your urlconf point to those apps-- so url(r'^/en/', include(myproject. en)) would be in your urlconf to point to your English app, and the other for the other language.

What is multilingual search?

In reality, a search system is multilingual if it is able to retrieve relevant documents from the database by matching the document's content, or captions, written in one language with the text query in another language.

How do I create a search query in Django?

You would use the __search operator. It's documented in the Django QuerySet API Reference. There's also istartswith, which does a case-insensitive starts-with search. Note that __search is only available in MySQL and requires direct manipulation of the database to add the full-text index.

What languages does Django support?

Here, you defined the available languages (English, French, Spanish) for django-parler. You also specified English as the default language and indicated that django-parler should not hide untranslated content.


1 Answers

This more of a starting point than a full solution, but I hope it help and that other users can improve this idea and reach a better solution.

Using Haystack to index a multilingual site (using django-transmeta or django-multilingual) you face two problems:

  1. how to index the content for all the languages
  2. how to search the query the correct index depending on the selected languages

1) Index the content for all the languages

Create a separate fields for each language in every SearchIndex model, using a common prefix and the language code:

text_en = indexes.CharField(model_attr='body_en', document=True) text_pt = indexes.CharField(model_attr='body_pt') 

If you want to index several fields you can obviously use a template. Only one of the indexes can have document=True.

If you need pre-rendered http://haystacksearch.org/docs/searchindex_api.html field for faster display, you should create one for each language (ie, rendered_en, rendered_pt)

2) Querying the correct index

The default haystack auto_query method is programmed to receive a "q" query parameter on the request and search the "content" index field - the one marked as document=True - in all the Index models. Only one of the indexes can have document=True and I believe we can only have a SearchIndex for each django Model.

The simplest solution, using the common search form, is to create a Multilingual SearchQuerySet that filters based, not on content, but on text_ (text being the prefix used on the Searchindex model above)

from django.conf import settings from django.utils.translation import get_language from haystack.query import SearchQuerySet, DEFAULT_OPERATOR  class MlSearchQuerySet(SearchQuerySet):     def filter(self, **kwargs):         """Narrows the search based on certain attributes and the default operator."""         if 'content' in kwargs:             kwd = kwargs.pop('content')             kwdkey = "text_%s" % str(get_language())             kwargs[kwdkey] = kwd         if getattr(settings, 'HAYSTACK_DEFAULT_OPERATOR', DEFAULT_OPERATOR) == 'OR':            return self.filter_or(**kwargs)         else:             return self.filter_and(**kwargs) 

and point your search URL to a view that uses this query set:

from haystack.forms import ModelSearchForm from haystack.views import SearchView  urlpatterns += patterns('haystack.views',     url(r'^search/$', SearchView(         searchqueryset=MlSearchQuerySet(),         form_class=ModelSearchForm     ), name='haystack_search_ml'), ) 

Now your search should be aware of the selected language.

like image 150
Nuno Maltez Avatar answered Sep 19 '22 19:09

Nuno Maltez