Currently I see two possibilities, with using locals()
and using setattr()
after definition of SearchIndex class:
1.
class TestIndex(indexes.SearchIndex, indexes.Indexable):
for name in fields:
locals()["attr_%s" % name] = DescriptionSearchField(boost=3, **{"d_attr": name, "name": "attr"})
locals()["slug_%s" % name] = DescriptionSearchField(**{"d_attr": name, "name": "slug"})
2.
class TestIndex(indexes.SearchIndex, indexes.Indexable):
pass
for name in fields:
setattr(JobTestIndex, "attr_%s" % name, DescriptionSearchField(boost=3, **{"d_attr": name, "name": "attr"}))
setattr(JobTestIndex, "slug_%s" % name, DescriptionSearchField(**{"d_attr": name, "name": "slug"}))
I am using Django-haystack with ElasticSearch.
I know that using locals()
is not the best practice.
What then is the correct approach to my issue?
Any suggestions are greatly appreciated. Thanks.
I decided to overwrite __new__()
method of DeclarativeMetaclass
, that is the metaclass of SearchIndex
.
So the part of the code now looks like this:
from haystack import indexes
from django.utils import six
from search_fields import DescriptionSearchField
class ChildDeclarativeMetaclass(indexes.DeclarativeMetaclass):
def __new__(cls, name, bases, attrs):
for f in reversed(attrs.pop("_extra_fields")):
attrs.update(f)
return super(ChildDeclarativeMetaclass, cls).__new__(cls, name, bases, attrs)
class OpenTaskIndex(six.with_metaclass(ChildDeclarativeMetaclass, indexes.SearchIndex, indexes.Indexable)):
text = indexes.CharField(document=True, use_template=True, template_name='search/indexes/job/open_task_text.txt')
_extra_fields = tuple((
("title_%s" % lang[0], DescriptionSearchField(boost=3, **{"d_lang": lang[0], "d_attr": "title"})),
("slug_%s" % lang[0], DescriptionSearchField(**{"d_lang": lang[0], "d_attr": "slug"})),
("text_%s" % lang[0], DescriptionSearchField(**{"d_lang": lang[0], "d_attr": "text_description"})))
for lang in settings.LANGUAGES
)
If you setting fields up after the class creation. They are not added to the attrs["fields"]
in DeclarativeMetaclass
.