Skip to content

Commit

Permalink
Merge 2872ebf into 6e6dd0f
Browse files Browse the repository at this point in the history
  • Loading branch information
gannetson committed Sep 16, 2022
2 parents 6e6dd0f + 2872ebf commit 99f1962
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 31 deletions.
6 changes: 4 additions & 2 deletions bluebottle/categories/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from bluebottle.initiatives.models import Initiative
from bluebottle.utils.widgets import SecureAdminURLFieldWidget
from .models import Category, CategoryContent
from ..utils.admin import TranslatableAdminOrderingMixin


class CategoryContentInline(SortableStackedInline, TranslatableStackedInline):
Expand All @@ -31,10 +32,11 @@ class CategoryInitiativesInline(TabularInline):
extra = 0


class CategoryAdmin(TranslatableAdmin, AdminImageMixin, NonSortableParentAdmin):
class CategoryAdmin(TranslatableAdminOrderingMixin, TranslatableAdmin, AdminImageMixin, NonSortableParentAdmin):
model = Category
list_display = ('slug', 'title', 'initiatives')
list_display = ('title', 'slug', 'initiatives')
inlines = (CategoryContentInline, CategoryInitiativesInline)
translatable_ordering = 'translations__title'

def initiatives(self, obj):
url = reverse('admin:initiatives_initiative_changelist')
Expand Down
2 changes: 1 addition & 1 deletion bluebottle/collect/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class CollectTypeList(TranslatedApiViewMixin, JsonApiViewMixin, ListAPIView):
pagination_class = NoPagination

def get_queryset(self):
return super().get_queryset().order_by('translations__name')
return super().get_queryset()


class CollectTypeDetail(TranslatedApiViewMixin, JsonApiViewMixin, RetrieveAPIView):
Expand Down
3 changes: 2 additions & 1 deletion bluebottle/geo/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Location, Country, Place,
Geolocation)
from bluebottle.initiatives.models import Initiative
from bluebottle.utils.admin import TranslatableAdminOrderingMixin


class LocationFilter(admin.SimpleListFilter):
Expand Down Expand Up @@ -38,7 +39,7 @@ def queryset(self, request, queryset):
return queryset


class CountryAdmin(TranslatableAdmin):
class CountryAdmin(TranslatableAdminOrderingMixin, TranslatableAdmin):
list_display = ('name', 'alpha2_code', 'alpha3_code', 'numeric_code')
search_fields = ('translations__name', 'alpha2_code', 'alpha3_code')
fields = ('name', 'alpha2_code', 'alpha3_code', 'numeric_code')
Expand Down
3 changes: 1 addition & 2 deletions bluebottle/geo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
from sorl.thumbnail import ImageField
from timezonefinder import TimezoneFinder

from bluebottle.utils.models import SortableTranslatableModel
from bluebottle.utils.validators import FileMimetypeValidator, validate_file_infection
from .validators import Alpha2CodeValidator, Alpha3CodeValidator, \
NumericCodeValidator
from ..utils.models import SortableTranslatableModel

tf = TimezoneFinder()

Expand Down Expand Up @@ -106,7 +106,6 @@ def code(self):
return self.alpha2_code

class Meta(GeoBaseModel.Meta):
ordering = ['translations__name']
verbose_name = _("country")
verbose_name_plural = _("countries")

Expand Down
13 changes: 7 additions & 6 deletions bluebottle/geo/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ def test_api_country_list_data(self):
"""
Ensure get request returns record with correct data.
"""
response = self.client.get(reverse('country-list'))

country = response.data[0]
response = self.client.get(
reverse('country-list'),
HTTP_X_APPLICATION_LANGUAGE='nl'
)

self.assertEqual(country['id'], self.country_1.id)
self.assertEqual(country['name'], self.country_1.name)
self.assertEqual(country['code'], 'GE')
countries = response.data
self.assertTrue('Abchazië' in [c['name'] for c in countries])
self.assertTrue('Zwitserland' in [c['name'] for c in countries])


class UsedCountryListTestCase(GeoTestCase):
Expand Down
3 changes: 2 additions & 1 deletion bluebottle/geo/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def get(self, request, *args, **kwargs):

def get_queryset(self):
qs = super(CountryList, self).get_queryset()

if 'filter[used]' in self.request.GET:
qs = qs.filter(
Q(location__initiative__status='approved') |
Expand All @@ -33,7 +34,7 @@ def get_queryset(self):
Q(geolocation__dateactivityslot__activity__status__in=self.public_statuses) &
Q(geolocation__dateactivityslot__status__in=self.public_statuses)
)
).distinct()
)
return qs


Expand Down
3 changes: 2 additions & 1 deletion bluebottle/impact/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from parler.admin import TranslatableAdmin

from bluebottle.impact.models import ImpactType, ImpactGoal
from bluebottle.utils.admin import TranslatableAdminOrderingMixin


class ImpactGoalInline(admin.TabularInline):
Expand All @@ -19,7 +20,7 @@ def unit(self, obj):
unit.short_description = _('Unit')


class ImpactTypeAdmin(TranslatableAdmin):
class ImpactTypeAdmin(TranslatableAdminOrderingMixin, TranslatableAdmin):
list_display = admin.ModelAdmin.list_display + ('name', 'active', 'activities')

def get_prepopulated_fields(self, request, obj=None):
Expand Down
4 changes: 2 additions & 2 deletions bluebottle/initiatives/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from bluebottle.geo.models import Location, Country
from bluebottle.initiatives.models import Initiative, InitiativePlatformSettings, Theme
from bluebottle.notifications.admin import MessageAdminInline, NotificationAdminMixin
from bluebottle.utils.admin import BasePlatformSettingsAdmin, export_as_csv_action
from bluebottle.utils.admin import BasePlatformSettingsAdmin, export_as_csv_action, TranslatableAdminOrderingMixin
from bluebottle.fsm.admin import StateMachineAdmin, StateMachineFilter
from bluebottle.fsm.forms import StateMachineModelForm
from bluebottle.wallposts.admin import WallpostInline
Expand Down Expand Up @@ -286,7 +286,7 @@ class InitiativePlatformSettingsAdmin(BasePlatformSettingsAdmin):


@admin.register(Theme)
class ThemeAdmin(TranslatableAdmin):
class ThemeAdmin(TranslatableAdminOrderingMixin, TranslatableAdmin):
list_display = admin.ModelAdmin.list_display + ('slug', 'disabled', 'initiative_link')
readonly_fields = ('initiative_link',)
fields = ('name', 'slug', 'description', 'disabled') + readonly_fields
Expand Down
47 changes: 47 additions & 0 deletions bluebottle/initiatives/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,53 @@ def test_detail_disabled(self):
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_detail_translation(self):
theme = ThemeFactory.create(slug='world', name='Zooi')
theme.set_current_language('en')
theme.name = 'World domination'
theme.save()
url = reverse('initiative-theme', args=(theme.id,))
response = self.client.get(
url,
user=self.user,
HTTP_X_APPLICATION_LANGUAGE='en'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
result = response.json()['data']
self.assertEqual(result['attributes']['name'], 'World domination')

def test_detail_translation_missing(self):
theme = ThemeFactory.create(slug='world')
theme.set_current_language('en')
theme.name = 'World domination'
theme.save()
url = reverse('initiative-theme', args=(theme.id,))
response = self.client.get(
url,
user=self.user,
HTTP_X_APPLICATION_LANGUAGE='nl'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
result = response.json()['data']
self.assertEqual(result['attributes']['name'], 'World domination')

def test_detail_translation_nl(self):
theme = ThemeFactory.create(slug='world')
theme.set_current_language('en')
theme.name = 'World domination'
theme.set_current_language('nl')
theme.name = 'Wereldoverheersing'
theme.save()
url = reverse('initiative-theme', args=(theme.id,))
response = self.client.get(
url,
user=self.user,
HTTP_X_APPLICATION_LANGUAGE='nl'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
result = response.json()['data']
self.assertEqual(result['attributes']['name'], 'Wereldoverheersing')


class ThemeApiTestCase(BluebottleTestCase):

Expand Down
2 changes: 1 addition & 1 deletion bluebottle/initiatives/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class ThemeList(TranslatedApiViewMixin, JsonApiViewMixin, ListAPIView):
pagination_class = NoPagination

def get_queryset(self):
return super().get_queryset().order_by('translations__name')
return super().get_queryset()


class ThemeDetail(TranslatedApiViewMixin, JsonApiViewMixin, RetrieveAPIView):
Expand Down
4 changes: 2 additions & 2 deletions bluebottle/time_based/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
)
from bluebottle.time_based.states import SlotParticipantStateMachine
from bluebottle.time_based.utils import nth_weekday, duplicate_slot
from bluebottle.utils.admin import export_as_csv_action
from bluebottle.utils.admin import export_as_csv_action, TranslatableAdminOrderingMixin
from bluebottle.utils.widgets import TimeDurationWidget, get_human_readable_duration


Expand Down Expand Up @@ -970,7 +970,7 @@ def get_fieldsets(self, request, obj=None):


@admin.register(Skill)
class SkillAdmin(TranslatableAdmin):
class SkillAdmin(TranslatableAdminOrderingMixin, TranslatableAdmin):
list_display = ('name', 'member_link')
readonly_fields = ('member_link',)
fields = readonly_fields + ('name', 'disabled', 'description', 'expertise')
Expand Down
4 changes: 2 additions & 2 deletions bluebottle/time_based/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3211,14 +3211,14 @@ def setUp(self):
MemberPlatformSettings.objects.update(closed=True)
self.url = reverse('skill-list')
Skill.objects.all().delete()
self.skill = SkillFactory.create_batch(40)
SkillFactory.create_batch(10)
self.client = JSONAPITestClient()

def test_get_skills_authenticated(self):
user = BlueBottleUserFactory.create()
response = self.client.get(self.url, user=user)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['results']), 40)
self.assertEqual(len(response.data['results']), 10)

def test_get_skills_unauthenticated(self):
response = self.client.get(self.url)
Expand Down
5 changes: 0 additions & 5 deletions bluebottle/time_based/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
ActivitySegmentPermission
)
from bluebottle.activities.views import RelatedContributorListView
from bluebottle.clients import properties
from bluebottle.initiatives.models import InitiativePlatformSettings
from bluebottle.members.models import MemberPlatformSettings
from bluebottle.segments.models import SegmentType
Expand Down Expand Up @@ -694,10 +693,6 @@ class SkillList(TranslatedApiViewMixin, JsonApiViewMixin, ListAPIView):
permission_classes = [TenantConditionalOpenClose, ]
pagination_class = SkillPagination

def get_queryset(self):
lang = self.request.LANGUAGE_CODE or properties.LANGUAGE_CODE
return super().get_queryset().translated(lang).order_by('translations__name')


class SkillDetail(TranslatedApiViewMixin, JsonApiViewMixin, RetrieveAPIView):
serializer_class = SkillSerializer
Expand Down
10 changes: 10 additions & 0 deletions bluebottle/utils/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,13 @@ def log_action(obj, user, change_message='Changed', action_flag=CHANGE):
@admin.register(TranslationPlatformSettings)
class TranslationPlatformSettingsAdmin(TranslatableAdmin, BasePlatformSettingsAdmin):
pass


class TranslatableAdminOrderingMixin(object):

translatable_ordering = 'translations__name'

def get_queryset(self, request):
language_code = self.get_queryset_language(request)
return super(TranslatableAdminOrderingMixin, self).get_queryset(request). \
translated(language_code).order_by(self.translatable_ordering)
10 changes: 5 additions & 5 deletions bluebottle/utils/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mimetypes
import os
import re
from io import BytesIO
from operator import attrgetter

Expand All @@ -15,7 +16,6 @@
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
from rest_framework.pagination import PageNumberPagination
Expand All @@ -32,7 +32,7 @@
from bluebottle.utils.permissions import ResourcePermission
from .models import Language
from .serializers import LanguageSerializer
import re
from .utils import get_current_language

mime = magic.Magic(mime=True)

Expand Down Expand Up @@ -232,9 +232,9 @@ def get_queryset(self):

class TranslatedApiViewMixin(object):
def get_queryset(self):
qs = super(TranslatedApiViewMixin, self).get_queryset().translated(
get_language()
)
qs = super(TranslatedApiViewMixin, self).get_queryset().active_translations(
get_current_language()
).distinct('id').order_by('id')
qs = qs.order_by(*qs.model._meta.ordering)
return qs

Expand Down

0 comments on commit 99f1962

Please sign in to comment.