From 2c5f0dcd6fb23a3b6cb4a5c29f33b43644e7be70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Mon, 9 Jan 2023 22:54:15 +0100 Subject: [PATCH] Use slugs to filter --- .../migrations/0011_company_slug_and_more.py | 93 +++++++++++++++++++ ram/metadata/models.py | 89 ++++++++++++------ ram/portal/templates/cards.html | 6 +- ram/portal/templates/companies.html | 2 +- ram/portal/templates/manufacturers.html | 2 +- ram/portal/templates/rollingstock.html | 10 +- ram/portal/templates/scales.html | 2 +- ram/portal/templates/types.html | 2 +- ram/portal/views.py | 31 ++----- ram/ram/__init__.py | 2 +- 10 files changed, 178 insertions(+), 61 deletions(-) create mode 100644 ram/metadata/migrations/0011_company_slug_and_more.py diff --git a/ram/metadata/migrations/0011_company_slug_and_more.py b/ram/metadata/migrations/0011_company_slug_and_more.py new file mode 100644 index 0000000..f12bf7b --- /dev/null +++ b/ram/metadata/migrations/0011_company_slug_and_more.py @@ -0,0 +1,93 @@ +# Generated by Django 4.1.5 on 2023-01-09 11:22 + +from django.db import migrations, models + + +from ram.utils import slugify + + +def create_slug(apps, schema_editor): + fields = ["Company", "Manufacturer", "RollingStockType", "Scale"] + + for m in fields: + model = apps.get_model("metadata", m) + + for row in model.objects.all(): + if hasattr(row, "type"): + row.slug = slugify("{} {}".format(row.type, row.category)) + elif hasattr(row, "scale"): + row.slug = slugify(row.scale) + else: + row.slug = slugify(row.name) + + row.save(update_fields=["slug"]) + + +class Migration(migrations.Migration): + + dependencies = [ + ("metadata", "0010_alter_manufacturer_category"), + ] + + operations = [ + migrations.AddField( + model_name="company", + name="slug", + field=models.CharField( + editable=False, max_length=64, blank=True + ), + ), + migrations.AddField( + model_name="manufacturer", + name="slug", + field=models.CharField( + editable=False, max_length=128, blank=True + ), + ), + migrations.AddField( + model_name="rollingstocktype", + name="slug", + field=models.CharField( + editable=False, max_length=128, blank=True + ), + ), + migrations.AddField( + model_name="scale", + name="slug", + field=models.CharField( + editable=False, max_length=32, blank=True + ), + ), + migrations.RunPython( + create_slug, + reverse_code=migrations.RunPython.noop + ), + migrations.AlterField( + model_name="company", + name="slug", + field=models.CharField( + editable=False, max_length=64, unique=True + ), + ), + migrations.AlterField( + model_name="manufacturer", + name="slug", + field=models.CharField( + editable=False, max_length=128, unique=True + ), + ), + migrations.AlterField( + model_name="rollingstocktype", + name="slug", + field=models.CharField( + editable=False, max_length=128, unique=True + ), + ), + migrations.AlterField( + model_name="scale", + name="slug", + field=models.CharField( + editable=False, max_length=32, unique=True + ), + ), + ] diff --git a/ram/metadata/models.py b/ram/metadata/models.py index ad38f77..ef79f07 100644 --- a/ram/metadata/models.py +++ b/ram/metadata/models.py @@ -1,6 +1,7 @@ from urllib.parse import quote from django.db import models +from django.urls import reverse from django.conf import settings from django.dispatch.dispatcher import receiver from django_countries.fields import CountryField @@ -22,6 +23,7 @@ class Property(models.Model): class Manufacturer(models.Model): name = models.CharField(max_length=128, unique=True) + slug = models.CharField(max_length=128, unique=True, editable=False) category = models.CharField( max_length=64, choices=settings.MANUFACTURER_TYPES ) @@ -36,8 +38,13 @@ class Manufacturer(models.Model): def __str__(self): return self.name - def safe_name(self): - return quote(self.__str__().lower(), safe="& ") + def get_absolute_url(self): + return reverse( + "filtered", kwargs={ + "_filter": "manufacturer", + "search": self.slug, + } + ) def logo_thumbnail(self): return get_image_preview(self.logo.url) @@ -47,6 +54,7 @@ class Manufacturer(models.Model): class Company(models.Model): name = models.CharField(max_length=64, unique=True) + slug = models.CharField(max_length=64, unique=True, editable=False) extended_name = models.CharField(max_length=128, blank=True) country = CountryField() freelance = models.BooleanField(default=False) @@ -61,8 +69,13 @@ class Company(models.Model): def __str__(self): return self.name - def safe_name(self): - return quote(self.__str__().lower(), safe="& ") + def get_absolute_url(self): + return reverse( + "filtered", kwargs={ + "_filter": "company", + "search": self.slug, + } + ) def logo_thumbnail(self): return get_image_preview(self.logo.url) @@ -94,6 +107,7 @@ class Decoder(models.Model): class Scale(models.Model): scale = models.CharField(max_length=32, unique=True) + slug = models.CharField(max_length=32, unique=True, editable=False) ratio = models.CharField(max_length=16, blank=True) gauge = models.CharField(max_length=16, blank=True) tracks = models.CharField(max_length=16, blank=True) @@ -101,11 +115,40 @@ class Scale(models.Model): class Meta: ordering = ["scale"] + def get_absolute_url(self): + return reverse( + "filtered", kwargs={ + "_filter": "scale", + "search": self.slug, + } + ) + def __str__(self): return str(self.scale) - def safe_name(self): - return quote(self.__str__(), safe="& ") + +class RollingStockType(models.Model): + type = models.CharField(max_length=64) + order = models.PositiveSmallIntegerField() + category = models.CharField( + max_length=64, choices=settings.ROLLING_STOCK_TYPES + ) + slug = models.CharField(max_length=128, unique=True, editable=False) + + class Meta(object): + unique_together = ("category", "type") + ordering = ["order"] + + def get_absolute_url(self): + return reverse( + "filtered", kwargs={ + "_filter": "type", + "search": self.slug, + } + ) + + def __str__(self): + return "{0} {1}".format(self.type, self.category) class Tag(models.Model): @@ -115,28 +158,20 @@ class Tag(models.Model): def __str__(self): return self.name - def safe_name(self): - return self.slug + def get_absolute_url(self): + return reverse( + "filtered", kwargs={ + "_filter": "tag", + "search": self.slug, + } + ) + +@receiver(models.signals.pre_save, sender=Manufacturer) +@receiver(models.signals.pre_save, sender=Company) +@receiver(models.signals.pre_save, sender=Scale) +@receiver(models.signals.pre_save, sender=RollingStockType) @receiver(models.signals.pre_save, sender=Tag) def slug_pre_save(sender, instance, **kwargs): - instance.slug = slugify(instance.name) - - -class RollingStockType(models.Model): - type = models.CharField(max_length=64) - order = models.PositiveSmallIntegerField() - category = models.CharField( - max_length=64, choices=settings.ROLLING_STOCK_TYPES - ) - - class Meta(object): - unique_together = ("category", "type") - ordering = ["order"] - - def __str__(self): - return "{0} {1}".format(self.type, self.category) - - def safe_name(self): - return quote(self.__str__().lower(), safe="& ") + instance.slug = slugify(instance.__str__()) diff --git a/ram/portal/templates/cards.html b/ram/portal/templates/cards.html index f9cc312..d2d3aa1 100644 --- a/ram/portal/templates/cards.html +++ b/ram/portal/templates/cards.html @@ -38,7 +38,7 @@ Company - {{ d.rolling_class.company }} + {{ d.rolling_class.company }} @@ -56,12 +56,12 @@ Manufacturer {%if d.manufacturer %} - {{ d.manufacturer }}{% if d.manufacturer.website %} {% endif %} + {{ d.manufacturer }}{% if d.manufacturer.website %} {% endif %} {% endif %} Scale - {{ d.scale }} + {{ d.scale }} SKU diff --git a/ram/portal/templates/companies.html b/ram/portal/templates/companies.html index 74d1087..b7fd706 100644 --- a/ram/portal/templates/companies.html +++ b/ram/portal/templates/companies.html @@ -42,7 +42,7 @@
- Show all rolling stock + Show all rolling stock {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/templates/manufacturers.html b/ram/portal/templates/manufacturers.html index dab3c8b..6ad0f8e 100644 --- a/ram/portal/templates/manufacturers.html +++ b/ram/portal/templates/manufacturers.html @@ -34,7 +34,7 @@
- Show all rolling stock + Show all rolling stock {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/templates/rollingstock.html b/ram/portal/templates/rollingstock.html index 7c0796a..04d9f53 100644 --- a/ram/portal/templates/rollingstock.html +++ b/ram/portal/templates/rollingstock.html @@ -70,7 +70,7 @@ Company - {{ rolling_stock.rolling_class.company }} + {{ rolling_stock.rolling_class.company }} @@ -97,7 +97,7 @@ Manufacturer {%if rolling_stock.manufacturer %} - {{ rolling_stock.manufacturer }}{% if rolling_stock.manufacturer.website %} {% endif %} + {{ rolling_stock.manufacturer }}{% if rolling_stock.manufacturer.website %} {% endif %} {% endif %} @@ -147,7 +147,7 @@ Manufacturer {%if rolling_stock.manufacturer %} - {{ rolling_stock.manufacturer }}{% if rolling_stock.manufacturer.website %} {% endif %} + {{ rolling_stock.manufacturer }}{% if rolling_stock.manufacturer.website %} {% endif %} {% endif %} @@ -209,7 +209,7 @@ Company - {{ rolling_stock.rolling_class.company }} ({{ rolling_stock.rolling_class.company.extended_name }}) + {{ rolling_stock.rolling_class.company }} ({{ rolling_stock.rolling_class.company.extended_name }}) @@ -219,7 +219,7 @@ Manufacturer {%if rolling_stock.rolling_class.manufacturer %} - {{ rolling_stock.rolling_class.manufacturer }}{% if rolling_stock.rolling_class.manufacturer.website %} {% endif %} + {{ rolling_stock.rolling_class.manufacturer }}{% if rolling_stock.rolling_class.manufacturer.website %} {% endif %} {% endif %} diff --git a/ram/portal/templates/scales.html b/ram/portal/templates/scales.html index bcf1ac1..dd3c609 100644 --- a/ram/portal/templates/scales.html +++ b/ram/portal/templates/scales.html @@ -32,7 +32,7 @@
- Show all rolling stock + Show all rolling stock {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/templates/types.html b/ram/portal/templates/types.html index f7de10d..32088b3 100644 --- a/ram/portal/templates/types.html +++ b/ram/portal/templates/types.html @@ -24,7 +24,7 @@
- Show all rolling stock + Show all rolling stock {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/views.py b/ram/portal/views.py index 1ffa269..26cfd2b 100644 --- a/ram/portal/views.py +++ b/ram/portal/views.py @@ -174,33 +174,22 @@ class GetRosterFiltered(View): def run_filter(self, request, search, _filter, page=1): site_conf = get_site_conf() if _filter == "type": - type_ = " ".join(search.split()[:-1]) - category = search.split()[-1] - try: - title = ( - RollingStockType.objects.filter(type__iexact=type_) - .get(category__iexact=category) - ) - except ObjectDoesNotExist: - raise Http404 - query = Q( - Q(rolling_class__type__type__iexact=type_) - & Q(rolling_class__type__category__iexact=category) - ) + title = RollingStockType.objects.get(slug__iexact=search) + query = Q(rolling_class__type__slug__iexact=search) elif _filter == "company": - title = get_object_or_404(Company, name__iexact=search) - query = Q(rolling_class__company__name__iexact=search) + title = get_object_or_404(Company, slug__iexact=search) + query = Q(rolling_class__company__slug__iexact=search) elif _filter == "manufacturer": - title = get_object_or_404(Manufacturer, name__iexact=search) + title = get_object_or_404(Manufacturer, slug__iexact=search) query = Q( - Q(rolling_class__manufacturer__name__iexact=search) - | Q(manufacturer__name__iexact=search) + Q(rolling_class__manufacturer__slug__iexact=search) + | Q(manufacturer__slug__iexact=search) ) elif _filter == "scale": - title = get_object_or_404(Scale, scale__iexact=search) - query = Q(scale__scale__iexact=search) + title = get_object_or_404(Scale, slug__iexact=search) + query = Q(scale__slug__iexact=search) elif _filter == "tag": - title = get_object_or_404(Tag, slug=search) + title = get_object_or_404(Tag, slug__iexact=search) query = Q(tags__slug__iexact=search) else: raise Http404 diff --git a/ram/ram/__init__.py b/ram/ram/__init__.py index bd13107..49e0602 100644 --- a/ram/ram/__init__.py +++ b/ram/ram/__init__.py @@ -1,4 +1,4 @@ from ram.utils import git_suffix -__version__ = "0.1.2" +__version__ = "0.2.0" __version__ += git_suffix(__file__)