diff --git a/hub/services/admin.py b/hub/services/admin.py index 2cebb43..8afe9d1 100644 --- a/hub/services/admin.py +++ b/hub/services/admin.py @@ -42,6 +42,7 @@ class ServiceLevelAdmin(admin.ModelAdmin): class ServiceAdmin(admin.ModelAdmin): list_display = ( "name", + "slug", "cloud_provider", "service_level", "price", @@ -49,7 +50,8 @@ class ServiceAdmin(admin.ModelAdmin): "category_list", ) list_filter = ("cloud_provider", "service_level", "countries", "categories") - search_fields = ("name", "description") + search_fields = ("name", "description", "slug") + prepopulated_fields = {"slug": ("name",)} filter_horizontal = ("countries", "categories") def logo_preview(self, obj): diff --git a/hub/services/migrations/0006_service_slug.py b/hub/services/migrations/0006_service_slug.py new file mode 100644 index 0000000..31a2cc6 --- /dev/null +++ b/hub/services/migrations/0006_service_slug.py @@ -0,0 +1,44 @@ +# Generated by Django 5.1.5 on 2025-01-27 15:57 + +from django.db import migrations, models +from django.utils.text import slugify + + +def generate_service_slugs(apps, schema_editor): + Service = apps.get_model("services", "Service") + + for service in Service.objects.all(): + base_slug = f"{service.name}-{service.cloud_provider.name}" + slug = slugify(base_slug) + + counter = 1 + while Service.objects.filter(slug=slug).exists(): + slug = f"{slugify(base_slug)}-{counter}" + counter += 1 + + service.slug = slug + service.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ("services", "0005_lead"), + ] + + operations = [ + migrations.AddField( + model_name="service", + name="slug", + field=models.SlugField(max_length=250, blank=True), + preserve_default=False, + ), + migrations.RunPython( + generate_service_slugs, reverse_code=migrations.RunPython.noop + ), + migrations.AlterField( + model_name="service", + name="slug", + field=models.SlugField(max_length=250, unique=True), + ), + ] diff --git a/hub/services/models.py b/hub/services/models.py index a4f47c4..f6576b3 100644 --- a/hub/services/models.py +++ b/hub/services/models.py @@ -1,5 +1,6 @@ from django.db import models from django.core.exceptions import ValidationError +from django.urls import reverse from django.utils.text import slugify from django_prose_editor.fields import ProseEditorField @@ -89,6 +90,7 @@ class ServiceLevel(models.Model): class Service(models.Model): name = models.CharField(max_length=200) + slug = models.SlugField(max_length=250, unique=True) description = ProseEditorField() cloud_provider = models.ForeignKey(CloudProvider, on_delete=models.CASCADE) service_level = models.ForeignKey(ServiceLevel, on_delete=models.CASCADE) @@ -108,6 +110,22 @@ class Service(models.Model): def __str__(self): return self.name + def save(self, *args, **kwargs): + if not self.slug: + base_slug = f"{self.name}-{self.cloud_provider.name}" + self.slug = slugify(base_slug) + + # If slug exists, append number + counter = 1 + while Service.objects.filter(slug=self.slug).exists(): + self.slug = f"{slugify(base_slug)}-{counter}" + counter += 1 + + super().save(*args, **kwargs) + + def get_absolute_url(self): + return reverse("services:service_detail", kwargs={"slug": self.slug}) + class Lead(models.Model): service = models.ForeignKey(Service, on_delete=models.CASCADE) diff --git a/hub/services/templates/services/lead_form.html b/hub/services/templates/services/lead_form.html index 32da988..4e1789a 100644 --- a/hub/services/templates/services/lead_form.html +++ b/hub/services/templates/services/lead_form.html @@ -67,7 +67,7 @@
diff --git a/hub/services/templates/services/service_detail.html b/hub/services/templates/services/service_detail.html index 249ada8..923cf5e 100644 --- a/hub/services/templates/services/service_detail.html +++ b/hub/services/templates/services/service_detail.html @@ -59,7 +59,7 @@ - Show Interest + Show Interest Back to Services diff --git a/hub/services/templates/services/service_list.html b/hub/services/templates/services/service_list.html index 975aa02..852d0c2 100644 --- a/hub/services/templates/services/service_list.html +++ b/hub/services/templates/services/service_list.html @@ -112,8 +112,8 @@ Price: ${{ service.price }} - View Details - Show Interest + View Details + Show Interest diff --git a/hub/services/urls.py b/hub/services/urls.py index ee5cfb1..c332763 100644 --- a/hub/services/urls.py +++ b/hub/services/urls.py @@ -5,8 +5,8 @@ app_name = "services" urlpatterns = [ path("", views.service_list, name="service_list"), - path("service/