recherche: première ébauche
[auf_framonde.git] / project / aldryn_search / base.py
CommitLineData
5f23ec55
PH
1# -*- coding: utf-8 -*-
2import warnings
3from django.utils.translation import override
4
5from haystack import indexes
6
7from .conf import settings
8from .helpers import get_request
9from .utils import clean_join, _get_language_from_alias_func
10
11
12language_from_alias = _get_language_from_alias_func()
13
14
15class AbstractIndex(indexes.SearchIndex):
16 text = indexes.CharField(document=True, use_template=False)
17
18 def _get_backend(self, using):
19 """
20 We set the backend to allow easy access for things like document search.
21 """
22 self._backend = super(AbstractIndex, self)._get_backend(using)
23 self._backend_alias = using
24 return self._backend
25
26 def index_queryset(self, using=None):
27 self._get_backend(using)
28 language = self.get_current_language(using)
29 filter_kwargs = self.get_index_kwargs(language)
30 qs = self.get_index_queryset(language)
31 return (qs.filter(**filter_kwargs))
32
33 def get_index_queryset(self, language):
34 return self.get_model().objects.all()
35
36 def prepare(self, obj):
37 current_language = self.get_current_language(
38 using=self._backend_alias, obj=obj)
39
40 with override(current_language):
41 request = self.get_request_instance(obj, current_language)
42 self.prepared_data = super(AbstractIndex, self).prepare(obj)
43 self.prepared_data['text'] = self.get_search_data(
44 obj, current_language, request)
45 self.prepare_fields(obj, current_language, request)
46 return self.prepared_data
47
48 def get_request_instance(self, obj, language):
49 return get_request(language)
50
51 def get_language(self, obj):
52 """
53 Equivalent to self.prepare_language.
54 """
55 return None
56
57 def get_current_language(self, using=None, obj=None):
58 """
59 Helper method bound to ALWAYS return a language.
60
61 When obj is not None, this calls self.get_language to try and get a language from obj,
62 this is useful when the object itself defines it's language in a "language" field.
63
64 If no language was found or obj is None, then we call self.get_default_language to try and get a fallback language.
65 """
66 language = self.get_language(obj) if obj else None
67 return language or self.get_default_language(using)
68
69 def get_default_language(self, using):
70 """
71 When using multiple languages, this allows us to specify a fallback based on the
72 backend being used.
73 """
74 language = None
75
76 if using and language_from_alias:
77 language = language_from_alias(using)
78 return language or settings.ALDRYN_SEARCH_DEFAULT_LANGUAGE
79
80 def get_index_kwargs(self, language):
81 """
82 This is called to filter the index queryset.
83 """
84 return {}
85
86 def get_search_data(self, obj, language, request):
87 """
88 Returns a string that will be used to populate the text field (primary field).
89 """
90 return ''
91
92 def prepare_fields(self, obj, language, request):
93 """
94 This is called to prepare any extra fields.
95 """
96 pass
97
98
99class AldrynIndexBase(AbstractIndex):
100 # For some apps it makes sense to turn on the title indexing.
101 index_title = False
102
103 language = indexes.CharField()
104 description = indexes.CharField(indexed=False, stored=True, null=True)
105 pub_date = indexes.DateTimeField(null=True)
106 login_required = indexes.BooleanField(default=False)
107 url = indexes.CharField(stored=True, indexed=False)
108 title = indexes.CharField(stored=True, indexed=False)
109 site_id = indexes.IntegerField(stored=True, indexed=True, null=True)
110
111 def __init__(self):
112 if hasattr(self, 'INDEX_TITLE'):
113 warning_message = 'AldrynIndexBase.INDEX_TITLE is deprecated; use AldrynIndexBase.index_title instead'
114 warnings.warn(warning_message, PendingDeprecationWarning)
115 super(AldrynIndexBase, self).__init__()
116
117 def get_url(self, obj):
118 """
119 Equivalent to self.prepare_url.
120 """
121 if not obj.get_absolute_url():
122 print obj
123 return obj.get_absolute_url()
124
125 def get_title(self, obj):
126 """
127 Equivalent to self.prepare_title.
128 """
129 return None
130
131 def get_description(self, obj):
132 """
133 Equivalent to self.prepare_description.
134 """
135 return None
136
137 def prepare_fields(self, obj, language, request):
138 self.prepared_data['language'] = language
139 # We set the following fields here because on some models,
140 # the value of these fields is dependent on the active language
141 # this being the case we extrapolate the language hacks.
142 self.prepared_data['url'] = self.get_url(obj)
143 self.prepared_data['title'] = self.get_title(obj)
144 self.prepared_data['description'] = self.get_description(obj)
145
146 if self.index_title or getattr(self, 'INDEX_TITLE', False):
147 prepared_text = self.prepared_data['text']
148 prepared_title = self.prepared_data['title']
149 self.prepared_data['text'] = clean_join(
150 ' ', [prepared_title, prepared_text])