django-haystack / django-haystack

Modular search for Django
http://haystacksearch.org/
Other
3.61k stars 1.3k forks source link

L10N issue executing rebuild_index or update_index #609

Open guglielmo opened 12 years ago

guglielmo commented 12 years ago

The LANGUAGE_CODE setting seem not to be active while in django shell. A simple way to reproduce the problem is:

1 set the following variables in settings

LANGUAGE_CODE = 'it-IT'
USE_I18N = True
USE_L10N = True

2 copy-paste these instructions in the django shell.

from django.utils import translation
print translation.get_language()

The output will be en-us, regardless of the settings.

Launching this as a python script, providing that the DJANGO_SETTINGS_MODULE variable is properly set, will output the correct it-it value.

This issue produces wrong index building, whenever using the prepare_template() method of SearchField to render values that need to be automatically converted for L10N reasons. For examples float values using USE_THOUSAND_SEPARATOR = True or dates.

The issue is minor and can easily be circumvented, by subclassing the SearchField and overwriting the prepare_template method, and then using the subclass in the search_indexes.py definitions.:

from django.utils import translation
from django.conf import settings
from haystack.fields import SearchField

class L10NCharField(SearchField):
    def prepare_template(self, obj):

        translation.activate(settings.LANGUAGE_CODE)
        return super(L10NCharField, self).prepare_template(obj)

Nevertheless it could be more easily addressed directly in the SerchField.prepare_render method. This could also be inspiring to find analogue issues around Haystack code.

pirax commented 10 years ago

The same issue affects SearchIndex and prepare_* methods. Calling update_index from shell causes wrong (not translated) index entries, generated with ugettext.

acdha commented 10 years ago

This is really an issue with Django: management commands force the locale to 'en-us'. Django 1.6 added the leave_locale_alone option to help with this:

https://docs.djangoproject.com/en/1.6/howto/custom-management-commands/#django.core.management.BaseCommand.leave_locale_alone

I think @bmihelac has the right solution in #933 for adding a --locale option to parallel the makemessages command.

acdha commented 10 years ago

Note also that there's currently no clean way to handle multilingual content when the backends are language-specific without using a custom update_index.py which overrides the Haystack default one like this:

# encoding: utf-8
from __future__ import absolute_import

from django.utils import translation
from haystack.management.commands.update_index import Command as DefaultCommand

class Command(DefaultCommand):
    def update_backend(self, label, using):
        with translation.override(using):
            super(Command, self).update_backend(label, using)

It feels like we should have an easier way to do this but it's something of an edge-case for many Haystack users.

pirax commented 10 years ago

Thanks. You are right, solution by @bmihelac in #933 seems correct.

acdha commented 10 years ago

@pirax In the meantime, should you need it the management command above should work in your project as well. If you just have a single language you could simplify it to override handle() instead of update_backend() and do the activation once at that level.