From 273e417da235ccfb83a0ac65f0a6bae41cc92a8b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 27 Jan 2025 17:00:56 +0100 Subject: [PATCH] slugify service --- hub/services/admin.py | 4 +- hub/services/migrations/0006_service_slug.py | 44 +++++++++++++++++++ hub/services/models.py | 18 ++++++++ .../templates/services/lead_form.html | 2 +- .../templates/services/service_detail.html | 2 +- .../templates/services/service_list.html | 4 +- hub/services/urls.py | 6 +-- hub/services/views.py | 14 +++--- 8 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 hub/services/migrations/0006_service_slug.py 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 @@
- Cancel + Cancel
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//", views.service_detail, name="service_detail"), - path("service//interest/", views.create_lead, name="create_lead"), - path("service//thank-you/", views.thank_you, name="thank_you"), + path("service//", views.service_detail, name="service_detail"), + path("service//interest/", views.create_lead, name="create_lead"), + path("service//thank-you/", views.thank_you, name="thank_you"), path("provider//", views.provider_detail, name="provider_detail"), ] diff --git a/hub/services/views.py b/hub/services/views.py index ff25602..981aa78 100644 --- a/hub/services/views.py +++ b/hub/services/views.py @@ -55,8 +55,8 @@ def service_list(request): return render(request, "services/service_list.html", context) -def service_detail(request, pk): - service = get_object_or_404(Service, pk=pk) +def service_detail(request, slug): + service = get_object_or_404(Service, slug=slug) return render(request, "services/service_detail.html", {"service": service}) @@ -70,13 +70,13 @@ def provider_detail(request, slug): return render(request, "services/provider_detail.html", context) -def thank_you(request, service_id): - service = get_object_or_404(Service, id=service_id) +def thank_you(request, slug): + service = get_object_or_404(Service, slug=slug) return render(request, "services/thank_you.html", {"service": service}) -def create_lead(request, service_id): - service = get_object_or_404(Service, id=service_id) +def create_lead(request, slug): + service = get_object_or_404(Service, slug=slug) if request.method == "POST": form = LeadForm(request.POST) @@ -92,7 +92,7 @@ def create_lead(request, service_id): lead.save() logger.info(f"Successfully created lead with Odoo ID: {odoo_lead_id}") - return redirect("services:thank_you", service_id=service.id) + return redirect("services:thank_you", slug=service.slug) except Exception as e: logger.error(f"Failed to create lead: {str(e)}", exc_info=True)