Skip to content

Commit

Permalink
Use old paginator for initiative search. Translate themes and skills
Browse files Browse the repository at this point in the history
  • Loading branch information
eodolphi committed Sep 5, 2022
1 parent f9f25df commit 611e18b
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 22 deletions.
44 changes: 30 additions & 14 deletions bluebottle/activities/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ActivityDocument(Document):
properties={
'id': fields.KeywordField(),
'name': fields.KeywordField(),
'language': fields.KeywordField(),
}
)

Expand Down Expand Up @@ -186,20 +187,17 @@ def prepare_location(self, instance):
'city': instance.location.locality,
})
if hasattr(instance, 'office_location') and instance.office_location:
location = {
'id': instance.office_location.pk,
'name': instance.office_location.name,
'city': instance.office_location.city,
}

if instance.office_location.country:
locations.append({
'id': instance.office_location.pk,
'name': instance.office_location.name,
'city': instance.office_location.city,
'country_code': instance.office_location.country.alpha2_code,
'country': instance.office_location.country.name
})
else:
locations.append({
'id': instance.office_location.pk,
'name': instance.office_location.name,
'city': instance.office_location.city,
})
location['country_code'] = instance.office_location.country.alpha2_code,
location['country'] = instance.office_location.country.name
locations.append(location)

elif instance.initiative.location:
if instance.initiative.location.country:
locations.append({
Expand All @@ -219,7 +217,25 @@ def prepare_location(self, instance):

def prepare_expertise(self, instance):
if hasattr(instance, 'expertise') and instance.expertise:
return {'id': instance.expertise_id}
return [
{
'id': instance.expertise_id,
'name': translation.name,
'language': translation.language_code,
}
for translation in instance.expertise.translations.all()
]

def prepare_theme(self, instance):
if hasattr(instance.initiative, 'theme') and instance.initiative.theme:
return [
{
'id': instance.initiative.theme_id,
'name': translation.name,
'language': translation.language_code,
}
for translation in instance.initiative.theme.translations.all()
]

def prepare_is_online(self, instance):
if hasattr(instance, 'is_online'):
Expand Down
27 changes: 22 additions & 5 deletions bluebottle/activities/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from bluebottle.utils.serializers import (
MoneySerializer
)
from bluebottle.utils.utils import get_current_language

IMAGE_SIZES = {
'preview': '300x168',
Expand All @@ -57,7 +58,7 @@ class ActivityImageSerializer(ImageSerializer):


class ActivityPreviewSerializer(ModelSerializer):
theme = serializers.CharField(source='theme.name')
theme = serializers.SerializerMethodField()
expertise = serializers.SerializerMethodField()
initiative = serializers.CharField(source='initiative.title')

Expand All @@ -74,8 +75,24 @@ class ActivityPreviewSerializer(ModelSerializer):
deadline = serializers.CharField(source='end')

def get_expertise(self, obj):
if obj.expertise:
return obj.expertise.name
try:
return [
expertise.name
for expertise in obj.expertise or []
if expertise.language == get_current_language()
][0]
except IndexError:
pass

def get_theme(self, obj):
try:
return [
theme.name
for theme in obj.theme or []
if theme.language == get_current_language()
][0]
except IndexError:
pass

def get_type(self, obj):
return obj.type.replace('activity', '')
Expand Down Expand Up @@ -115,8 +132,8 @@ def get_matching_options(self, obj):
self.context['location'] = user.location or user.place

matching = {}
matching['skill'] = obj.expertise.id in self.context['skills'] if obj.expertise else False
matching['theme'] = obj.theme.id in self.context['themes'] if obj.theme else False
matching['skill'] = obj.expertise[0].id in self.context['skills'] if obj.expertise else False
matching['theme'] = obj.theme[0].id in self.context['themes'] if obj.theme else False

if obj.is_online:
matching['location'] = True
Expand Down
2 changes: 1 addition & 1 deletion bluebottle/utils/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def filter_queryset(self, request, queryset, view):
except AttributeError:
search = search.sort(*sort)

return search
return (queryset, search)

def get_filter_fields(self, request):
return [
Expand Down
56 changes: 54 additions & 2 deletions bluebottle/utils/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import xlsxwriter
from django.core.paginator import Paginator
from django.core.signing import TimestampSigner, BadSignature
from django.db.models import Case, When, IntegerField
from django.http import Http404, HttpResponse
from django.utils import translation
from django.utils.functional import cached_property
from django.views.generic import TemplateView
from django.views.generic.base import View
from django.views.generic.detail import DetailView

from parler.utils.i18n import get_language
from rest_framework import generics
from rest_framework import views, response
Expand Down Expand Up @@ -238,13 +240,62 @@ def get_queryset(self):
return qs


class ESDBPaginator(Paginator):
@cached_property
def count(self):
"""
Returns the total number of objects, across all pages.
"""
if isinstance(self.object_list, tuple):
_, object_list = self.object_list
else:
object_list = self.object_list

try:
return object_list.count()
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
return len(object_list)

def page(self, number):
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page

if top + self.orphans >= self.count:
top = self.count

if isinstance(self.object_list, tuple):
queryset, search = self.object_list
page = self._get_page(search[bottom:top], number, self)

try:
pks = [result.meta.id for result in search[bottom:top].execute()]
queryset = queryset.filter(pk__in=pks)
except ValueError:
pks = search.to_queryset().values_list('id', flat=True)
queryset = search.to_queryset()

preserved_order = Case(
*[When(pk=pk, then=pos) for pos, pk in enumerate(pks)],
output_field=IntegerField()
)
page.object_list = queryset.annotate(search_order=preserved_order).order_by('search_order')
else:
page = self._get_page(self.object_list[bottom:top], number, self)

return page


class ESPaginator(Paginator):
@cached_property
def count(self):
"""
Returns the total number of objects, across all pages.
"""
return self.object_list.count()
return self.object_list[1].count()

def page(self, number):
number = self.validate_number(number)
Expand All @@ -254,12 +305,13 @@ def page(self, number):
if top + self.orphans >= self.count:
top = self.count

return self._get_page(self.object_list[bottom:top].execute(), number, self)
return self._get_page(self.object_list[1][bottom:top].execute(), number, self)


class JsonApiPagination(JsonApiPageNumberPagination):
page_size = 8
max_page_size = None
django_paginator_class = ESDBPaginator


class JsonApiElasticSearchPagination(JsonApiPageNumberPagination):
Expand Down

0 comments on commit 611e18b

Please sign in to comment.