diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-30 11:28:56 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-30 11:28:56 +0200 |
commit | c073239b4ff54fdf9334e53137219c4da611118c (patch) | |
tree | 34e5cd326e2f5380ddd4ecfb10d712fde1cd28ef /chimere | |
parent | 4d7c7c9410d86160cfac73c0e1ace599b9e34a73 (diff) | |
download | Chimère-c073239b4ff54fdf9334e53137219c4da611118c.tar.bz2 Chimère-c073239b4ff54fdf9334e53137219c4da611118c.zip |
Manage search pagination
Diffstat (limited to 'chimere')
-rw-r--r-- | chimere/models.py | 36 | ||||
-rw-r--r-- | chimere/templates/search/search.html | 6 | ||||
-rw-r--r-- | chimere/views.py | 40 |
3 files changed, 63 insertions, 19 deletions
diff --git a/chimere/models.py b/chimere/models.py index 46a778c..451596b 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -609,6 +609,7 @@ class GeographicItem(models.Model): search_vector = SearchVectorField(_("Search vector"), blank=True, null=True, help_text=_("Auto filled at save")) + geom_attr = '' default_values = {} json_color_keys = [] @@ -861,7 +862,8 @@ class GeographicItem(models.Model): raise NotImplementedError() @classmethod - def getGeoJSONs(cls, queryset, limit_to_categories=None, slice=None): + def getGeoJSONs(cls, queryset, limit_to_categories=None, slice=None, + check_next=False): default_values = copy.copy(cls.default_values) q_values = ['json', 'name', 'pk', 'categories__pk'] + \ cls.json_color_keys @@ -873,9 +875,8 @@ class GeographicItem(models.Model): start, end = 0, None if slice: start, end = slice + has_next = False for item in q.all(): - if end and len(vals) > end: - break if item['pk'] in added: continue if limit_to_categories and \ @@ -884,7 +885,11 @@ class GeographicItem(models.Model): added.append(item['pk']) if start: start -= 1 + end -= 1 continue + if end and len(vals) > end: + has_next = True + break properties = {"pk": item['pk'], "name": item['name'], 'key': "{}-{}".format(cls.geom_attr, item['pk'])} icon_and_colors, current_categories = \ @@ -905,18 +910,24 @@ class GeographicItem(models.Model): "geometry": geom, "properties": properties }) - return vals + if not check_next: + return vals + return vals, has_next @classmethod - def search(cls, query, area=None, get_json=False, slice=None): + def search(cls, query, area=None, get_json=False, slice=None, + check_next=False): """ Search items using search_vector :param query: terms to search :param area: area limitation (default None) :param get_json: output as json if True else return a queryset - :param slice: startting and ending bounds - :return: items matching the search query and the area + :param slice: starting and ending bounds + :param check_next: check if next items are available (only relevant + if a slice is provided) + :return: items matching the search query - if check next to true + also return if next items are available """ subcats = SubCategory.getAvailable(instance=True, area=area) q = cls.objects.filter(categories__in=subcats, @@ -924,11 +935,16 @@ class GeographicItem(models.Model): query, config=settings.CHIMERE_SEARCH_LANGUAGE)) if get_json: - return cls.getGeoJSONs(q, slice=slice) + return cls.getGeoJSONs(q, slice=slice, check_next=check_next) if slice: - return q.all()[slice[0]:slice[1]] + if not check_next: + return q.all()[slice[0]:slice[1]] + has_next = q.count() > slice[1] + return q.all()[slice[0]:slice[1]], has_next else: - return q.all() + if not check_next: + return q.all() + return q.all(), False def update_search_vector(self, save=True): """ diff --git a/chimere/templates/search/search.html b/chimere/templates/search/search.html index d01c16e..67e08d9 100644 --- a/chimere/templates/search/search.html +++ b/chimere/templates/search/search.html @@ -18,12 +18,12 @@ var end_do_you_mean = "{% trans '?' %}"; {% endfor %} </ul> </div> -{% if page.has_previous or page.has_next %} +{% if previous_page_number or next_page_number %} <div id='search-nav'> <nav> <ul class="pager"> - {% if page.has_previous %}<li class="previous"><a href="#" onclick="haystack_search(this, {{ page.previous_page_number }});">← {% trans "Previous" %}</a></li>{% endif %} - {% if page.has_next %}<li class="next"><a href="#" onclick="haystack_search(this, {{ page.next_page_number }});">{% trans "More results..." %} →</a></li>{% endif %} + {% if previous_page_number %}<li class="previous"><a href="#" onclick="haystack_search(this, {{ previous_page_number }});"><i class="fa fa-arrow-circle-left" aria-hidden="true"></i> {% trans "Previous" %}</a></li>{% endif %} + {% if next_page_number %}<li class="next"><a href="#" onclick="haystack_search(this, {{ next_page_number }});">{% trans "More results..." %} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a></li>{% endif %} </ul> </nav> </div> diff --git a/chimere/views.py b/chimere/views.py index ee27d26..d486506 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -1278,23 +1278,51 @@ class SearchView(FormView): form_class = forms.SearchForm results_per_page = settings.SEARCH_RESULTS_PER_PAGE - def get_results(self, query, area=None): - results = [] + def get_results(self, query, area=None, page=1): + results, has_next = [], False + start = (page - 1) * self.results_per_page + end = page * self.results_per_page - 1 for model in [models.Marker, models.Route, models.Polygon]: - results += model.search(query, area=area, get_json=True) - return results + if len(results) > end - len(results): + continue + res, _has_next = model.search( + query, area=area, get_json=True, + slice=[start, end], + check_next=True) + if _has_next: + has_next = True + if res: + if start: + end = end - start + start = 0 + end -= len(res) + results += res + return results, has_next def get_context_data(self, **kwargs): context = super(SearchView, self).get_context_data(**kwargs) area, area_name = get_area(self.kwargs.get('area_name', None)) query, results = None, [] + previous_page_number, next_page_number = None, None if "q" in self.request.GET: query = self.request.GET['q'] - results = self.get_results(query, area) + try: + page = int(self.request.GET.get('page', 1)) + assert page >= 1 + except (ValueError, AssertionError): + page = 1 + if page > 1: + previous_page_number = page - 1 + results, has_next = self.get_results(query, area, page=page) + if has_next: + next_page_number = page + 1 + context.update({ 'query': query, 'results': results, - 'area_name': area_name + 'area_name': area_name, + 'previous_page_number': previous_page_number, + 'next_page_number': next_page_number }) # (paginator, page) = self.build_page() |