From 2ab2d0058542211dbc172bd7a1edf456836f5919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Sat, 3 Jan 2026 00:54:21 +0100 Subject: [PATCH] Improve ordering --- ram/portal/admin.py | 1 + ...ration_featured_items_ordering_and_more.py | 43 ++++++++++++++++++ ram/portal/models.py | 11 +++-- ram/portal/views.py | 44 +++++++++++-------- 4 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 ram/portal/migrations/0021_siteconfiguration_featured_items_ordering_and_more.py diff --git a/ram/portal/admin.py b/ram/portal/admin.py index 50d8ec7..8bb4b99 100644 --- a/ram/portal/admin.py +++ b/ram/portal/admin.py @@ -20,6 +20,7 @@ class SiteConfigurationAdmin(SingletonModelAdmin): "about", "items_per_page", "items_ordering", + "featured_items_ordering", "currency", "footer", "footer_extended", diff --git a/ram/portal/migrations/0021_siteconfiguration_featured_items_ordering_and_more.py b/ram/portal/migrations/0021_siteconfiguration_featured_items_ordering_and_more.py new file mode 100644 index 0000000..2c4e7d9 --- /dev/null +++ b/ram/portal/migrations/0021_siteconfiguration_featured_items_ordering_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 6.0 on 2026-01-02 23:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("portal", "0020_alter_flatpage_options"), + ] + + operations = [ + migrations.AddField( + model_name="siteconfiguration", + name="featured_items_ordering", + field=models.CharField( + choices=[ + ("type", "By rolling stock type and company"), + ("class", "By rolling stock type and class"), + ("company", "By company and type"), + ("country", "By country and type"), + ("cou+com", "By country and company"), + ], + default="type", + max_length=11, + ), + ), + migrations.AlterField( + model_name="siteconfiguration", + name="items_ordering", + field=models.CharField( + choices=[ + ("type", "By rolling stock type and company"), + ("class", "By rolling stock type and class"), + ("company", "By company and type"), + ("country", "By country and type"), + ("cou+com", "By country and company"), + ], + default="type", + max_length=11, + ), + ), + ] diff --git a/ram/portal/models.py b/ram/portal/models.py index b05aa35..b3fe41e 100644 --- a/ram/portal/models.py +++ b/ram/portal/models.py @@ -22,14 +22,17 @@ class SiteConfiguration(SingletonModel): default="6", ) items_ordering = models.CharField( - max_length=10, + max_length=11, choices=[ - ("type", "By rolling stock type"), - ("company", "By company name"), - ("identifier", "By rolling stock class"), + ("type", "By rolling stock type and company"), + ("class", "By rolling stock type and class"), + ("company", "By company and type"), + ("country", "By country and type"), + ("cou+com", "By country and company"), ], default="type", ) + featured_items_ordering = items_ordering.clone() currency = models.CharField(max_length=3, default="EUR") footer = tinymce.HTMLField(blank=True) footer_extended = tinymce.HTMLField(blank=True) diff --git a/ram/portal/views.py b/ram/portal/views.py index 9684b7b..a3a80e3 100644 --- a/ram/portal/views.py +++ b/ram/portal/views.py @@ -36,25 +36,29 @@ def get_items_per_page(): return int(items_per_page) -def get_order_by_field(): +def get_items_ordering(config="items_ordering"): try: - order_by = get_site_conf().items_ordering + order_by = getattr(get_site_conf(), config) except (OperationalError, ProgrammingError): order_by = "type" fields = [ - "rolling_class__type", - "rolling_class__company", - "rolling_class__identifier", - "road_number_int", + "rolling_class__type", # 0 + "rolling_class__company", # 1 + "rolling_class__company__country", # 2 + "rolling_class__identifier", # 3 + "road_number_int", # 4 ] - if order_by == "type": - return (fields[0], fields[1], fields[2], fields[3]) - elif order_by == "company": - return (fields[1], fields[0], fields[2], fields[3]) - elif order_by == "identifier": - return (fields[2], fields[0], fields[1], fields[3]) + order_map = { + "type": (0, 1, 3, 4), + "company": (1, 0, 3, 4), + "country": (2, 0, 1, 3, 4), + "cou+com": (2, 1, 0, 3, 4), + "class": (0, 3, 1, 4), + } + + return tuple(fields[i] for i in order_map.get(order_by, "type")) class Render404(View): @@ -70,7 +74,7 @@ class GetData(View): def get_data(self, request): return ( RollingStock.objects.get_published(request.user) - .order_by(*get_order_by_field()) + .order_by(*get_items_ordering()) .filter(self.filter) ) @@ -107,7 +111,9 @@ class GetHome(GetData): return ( RollingStock.objects.get_published(request.user) .filter(featured=True) - .order_by(*get_order_by_field())[:max_items] + .order_by(*get_items_ordering(config="featured_items_ordering"))[ + :max_items + ] ) or super().get_data(request) @@ -174,7 +180,7 @@ class SearchObjects(View): RollingStock.objects.get_published(request.user) .filter(query) .distinct() - .order_by(*get_order_by_field()) + .order_by(*get_items_ordering()) ) data = list(roster) @@ -301,7 +307,7 @@ class GetManufacturerItem(View): if search != "all": roster = get_list_or_404( RollingStock.objects.get_published(request.user).order_by( - *get_order_by_field() + *get_items_ordering() ), Q( Q(manufacturer=manufacturer) @@ -323,7 +329,7 @@ class GetManufacturerItem(View): | Q(rolling_class__manufacturer=manufacturer) ) .distinct() - .order_by(*get_order_by_field()) + .order_by(*get_items_ordering()) ) catalogs = Catalog.objects.get_published(request.user).filter( manufacturer=manufacturer @@ -376,7 +382,7 @@ class GetObjectsFiltered(View): RollingStock.objects.get_published(request.user) .filter(query) .distinct() - .order_by(*get_order_by_field()) + .order_by(*get_items_ordering()) ) data = list(roster) @@ -480,7 +486,7 @@ class GetRollingStock(View): & Q(set=True) ) ) - .order_by(*get_order_by_field()) + .order_by(*get_items_ordering()) ) return render(