diff --git a/src/aurora/api/serializers/record.py b/src/aurora/api/serializers/record.py index 642013ee..c10cbdf9 100644 --- a/src/aurora/api/serializers/record.py +++ b/src/aurora/api/serializers/record.py @@ -14,10 +14,10 @@ class RecordSerializer(serializers.ModelSerializer): registration_url = serializers.SerializerMethodField() registrar = serializers.CharField() - project = serializers.ReadOnlyField(source='registration.project.pk') - organization = serializers.ReadOnlyField(source='registration.project.organization.pk') - project_slug = serializers.ReadOnlyField(source='registration.project.slug') - organization_slug = serializers.ReadOnlyField(source='registration.project.organization.slug') + project = serializers.ReadOnlyField(source="registration.project.pk") + organization = serializers.ReadOnlyField(source="registration.project.organization.pk") + project_slug = serializers.ReadOnlyField(source="registration.project.slug") + organization_slug = serializers.ReadOnlyField(source="registration.project.organization.slug") class Meta: model = Record diff --git a/src/aurora/api/viewsets/record.py b/src/aurora/api/viewsets/record.py index 9db5e9d5..ab1a3757 100644 --- a/src/aurora/api/viewsets/record.py +++ b/src/aurora/api/viewsets/record.py @@ -14,7 +14,7 @@ class RecordFilter(filters.FilterSet): class Meta: model = Record - fields = ["registration", "after", "id", "registration__project", "registration__project__organization"] + fields = ["registration", "after", "id", "registration__project", "registration__project__organization"] class RecordPaginator(CursorPagination): diff --git a/src/aurora/config/fragments/smart_admin.py b/src/aurora/config/fragments/smart_admin.py index 3ff4d41e..16edf46f 100644 --- a/src/aurora/config/fragments/smart_admin.py +++ b/src/aurora/config/fragments/smart_admin.py @@ -1,4 +1,3 @@ -from .. import env SMART_ADMIN_SECTIONS = { "Registration": ["registration", "dbtemplates", "flatpages"], diff --git a/src/aurora/core/admin/custom_field.py b/src/aurora/core/admin/custom_field.py index 823d99e7..7edf0dc8 100644 --- a/src/aurora/core/admin/custom_field.py +++ b/src/aurora/core/admin/custom_field.py @@ -4,6 +4,7 @@ from django.contrib.admin import register from django.core.cache import caches from django.db.models import JSONField +from django.db.models.functions import Collate from admin_extra_buttons.decorators import button from jsoneditor.forms import JSONEditor @@ -24,11 +25,19 @@ class CustomFieldTypeAdmin(SmartModelAdmin): "base_type", "attrs", ) - search_fields = ("name",) + search_fields = ("name_deterministic",) formfield_overrides = { JSONField: {"widget": JSONEditor}, } + def get_queryset(self, request): + return ( + super() + .get_queryset(request) + .annotate(name_deterministic=Collate("name", "und-x-icu")) + .select_related("flex_form") + ) + @button() def test(self, request, pk): ctx = self.get_common_context(request, pk) diff --git a/src/aurora/core/admin/flex_field.py b/src/aurora/core/admin/flex_field.py index 3f8ebcc5..4b064ca1 100644 --- a/src/aurora/core/admin/flex_field.py +++ b/src/aurora/core/admin/flex_field.py @@ -5,6 +5,7 @@ from django.contrib.admin import register from django.core.cache import caches from django.db.models import JSONField +from django.db.models.functions import Collate from admin_extra_buttons.decorators import button, view from admin_ordering.admin import OrderableAdmin @@ -42,7 +43,7 @@ def clean(self): @register(FlexFormField) class FlexFormFieldAdmin(LoadDumpMixin, SyncMixin, ConcurrencyVersionAdmin, OrderableAdmin, SmartModelAdmin): - search_fields = ("name", "label") + search_fields = ("name_deterministic", "label") list_display = ("label", "name", "flex_form", "field_type", "required", "enabled") list_editable = ["required", "enabled"] list_filter = ( @@ -61,7 +62,12 @@ class FlexFormFieldAdmin(LoadDumpMixin, SyncMixin, ConcurrencyVersionAdmin, Orde readonly_fields = ("version", "last_update_date") def get_queryset(self, request): - return super().get_queryset(request).select_related("flex_form") + return ( + super() + .get_queryset(request) + .annotate(name_deterministic=Collate("name", "und-x-icu")) + .select_related("flex_form") + ) # change_list_template = "reversion/change_list.html" def get_readonly_fields(self, request, obj=None): diff --git a/src/aurora/core/admin/flex_form.py b/src/aurora/core/admin/flex_form.py index f1f4da76..6bf63fb1 100644 --- a/src/aurora/core/admin/flex_form.py +++ b/src/aurora/core/admin/flex_form.py @@ -4,6 +4,7 @@ from django.contrib import messages from django.contrib.admin import register, TabularInline from django.core.cache import caches +from django.db.models.functions import Collate from admin_extra_buttons.decorators import button, view from admin_ordering.admin import OrderableAdmin @@ -85,7 +86,7 @@ class FlexFormAdmin(SyncMixin, ConcurrencyVersionAdmin, SmartModelAdmin): ("formset", UsedInRFormset), ("formset__parent", UsedInRFormset), ) - search_fields = ("name",) + search_fields = ("name_deterministic",) readonly_fields = ("version", "last_update_date") autocomplete_fields = ("validator", "project") ordering = ("name",) @@ -95,6 +96,7 @@ def get_queryset(self, request): return ( super() .get_queryset(request) + .annotate(name_deterministic=Collate("name", "und-x-icu")) .prefetch_related("registration_set") .select_related( "project", diff --git a/src/aurora/core/admin/optionset.py b/src/aurora/core/admin/optionset.py index 0759106f..fb3b5819 100644 --- a/src/aurora/core/admin/optionset.py +++ b/src/aurora/core/admin/optionset.py @@ -2,6 +2,7 @@ from django.contrib.admin import register from django.core.cache import caches +from django.db.models.functions import Collate from django.urls import NoReverseMatch from admin_extra_buttons.decorators import button, link @@ -28,13 +29,16 @@ class OptionSetAdmin(LoadDumpMixin, SyncMixin, ConcurrencyVersionAdmin, SmartMod "comment", "pk_col", ) - search_fields = ("name",) + search_fields = ("name_deterministic",) list_filter = (("data", ValueFilter.factory(lookup_name="icontains")),) save_as = True readonly_fields = ("version", "last_update_date") object_history_template = "reversion-compare/object_history.html" exclude = ("columns",) + def get_queryset(self, request): + return super().get_queryset(request).annotate(name_deterministic=Collate("name", "und-x-icu")) + @button() def display_data(self, request, pk): ctx = self.get_common_context(request, pk, title="Data") diff --git a/src/aurora/core/admin/organization.py b/src/aurora/core/admin/organization.py index 9c421ca7..c282f7a1 100644 --- a/src/aurora/core/admin/organization.py +++ b/src/aurora/core/admin/organization.py @@ -2,6 +2,7 @@ from django.contrib.admin import register from django.core.cache import caches +from django.db.models.functions import Collate from adminfilters.mixin import AdminAutoCompleteSearchMixin from mptt.admin import MPTTModelAdmin @@ -21,10 +22,19 @@ class OrganizationAdmin(SyncMixin, AdminAutoCompleteSearchMixin, LinkedObjectsMi list_display = ("name",) mptt_level_indent = 20 mptt_indent_field = "name" - search_fields = ("name",) + search_fields = ("name_deterministic",) protocol_class = AuroraSyncOrganizationProtocol change_list_template = "admin/core/organization/change_list.html" + def get_queryset(self, request): + return ( + super() + .get_queryset(request) + .annotate( + name_deterministic=Collate("name", "und-x-icu"), + ) + ) + def admin_sync_show_inspect(self): return True diff --git a/src/aurora/core/admin/project.py b/src/aurora/core/admin/project.py index ca836d6b..318c0ccc 100644 --- a/src/aurora/core/admin/project.py +++ b/src/aurora/core/admin/project.py @@ -2,9 +2,9 @@ from django.contrib.admin import register from django.core.cache import caches +from django.db.models.functions import Collate from adminfilters.mixin import AdminAutoCompleteSearchMixin -from django.db.models.functions import Collate from mptt.admin import MPTTModelAdmin from smart_admin.mixins import LinkedObjectsMixin @@ -23,14 +23,19 @@ class ProjectAdmin(SyncMixin, AdminAutoCompleteSearchMixin, LinkedObjectsMixin, list_filter = ("organization",) mptt_level_indent = 20 mptt_indent_field = "name" - search_fields = ("name",) + search_fields = ("name_deterministic",) protocol_class = AuroraSyncProjectProtocol autocomplete_fields = "parent, " def get_queryset(self, request): - return super().get_queryset(request).annotate( - name_deterministic=Collate("name", "und-x-icu"), - ).select_related("organization") + return ( + super() + .get_queryset(request) + .annotate( + name_deterministic=Collate("name", "und-x-icu"), + ) + .select_related("organization") + ) # # def get_search_results(self, request, queryset, search_term): diff --git a/src/aurora/core/fields/widgets/__init__.py b/src/aurora/core/fields/widgets/__init__.py index 7e3e7a52..b5df1e7a 100644 --- a/src/aurora/core/fields/widgets/__init__.py +++ b/src/aurora/core/fields/widgets/__init__.py @@ -1,7 +1,6 @@ from .datetime import SmartDateWidget from .editor import JavascriptEditor from .image import ImageWidget - # from .multi_checkbox import MultiCheckboxWidget from .number import NumberWidget from .radio import RadioWidget, YesNoRadioWidget diff --git a/src/aurora/core/templatetags/matomo.py b/src/aurora/core/templatetags/matomo.py index 9a59568d..15554806 100644 --- a/src/aurora/core/templatetags/matomo.py +++ b/src/aurora/core/templatetags/matomo.py @@ -11,4 +11,4 @@ def matomo_site(): @register.simple_tag() def matomo_id(): - return getattr(settings, 'MATOMO_ID', '') + return getattr(settings, "MATOMO_ID", "") diff --git a/src/aurora/registration/admin/registration.py b/src/aurora/registration/admin/registration.py index 84d540c6..024b30d0 100644 --- a/src/aurora/registration/admin/registration.py +++ b/src/aurora/registration/admin/registration.py @@ -103,9 +103,14 @@ class RegistrationAdmin(ConcurrencyVersionAdmin, AdminAutoCompleteSearchMixin, S protocol_class = AuroraSyncRegistrationProtocol def get_queryset(self, request): - return super().get_queryset(request).annotate( - name_deterministic=Collate("name", "und-x-icu"), - ).select_related("project", "project__organization") + return ( + super() + .get_queryset(request) + .annotate( + name_deterministic=Collate("name", "und-x-icu"), + ) + .select_related("project", "project__organization") + ) # def get_search_results(self, request, queryset, search_term): # queryset, may_have_duplicates = super().get_search_results(request, queryset, search_term) @@ -146,15 +151,15 @@ def media(self): extra = "" if settings.DEBUG else ".min" base = super().media return ( - VersionMedia( - js=[ - "admin/js/vendor/jquery/jquery%s.js" % extra, - "admin/js/jquery.init.js", - "jquery.compat%s.js" % extra, - "clipboard%s.js" % extra, - ] - ) - + base + VersionMedia( + js=[ + "admin/js/vendor/jquery/jquery%s.js" % extra, + "admin/js/jquery.init.js", + "jquery.compat%s.js" % extra, + "clipboard%s.js" % extra, + ] + ) + + base ) @view(permission=can_export_data) diff --git a/src/aurora/web/middlewares/admin.py b/src/aurora/web/middlewares/admin.py index e7cf01ec..5cddc41f 100644 --- a/src/aurora/web/middlewares/admin.py +++ b/src/aurora/web/middlewares/admin.py @@ -7,8 +7,6 @@ from constance import config -from aurora.core.utils import is_root - logger = logging.getLogger(__name__)