only show relevant filters on service listing

This commit is contained in:
Tobias Brunner 2025-03-03 17:28:38 +01:00
parent 7f76948875
commit b11fa2c21b
No known key found for this signature in database
2 changed files with 109 additions and 44 deletions

View file

@ -86,12 +86,12 @@
<div> <div>
<select class="form-select" id="category" name="category" @change="submitForm()"> <select class="form-select" id="category" name="category" @change="submitForm()">
<option value="">All Categories</option> <option value="">All Categories</option>
{% for category in categories %} {% for category in available_categories %}
<option value="{{ category.id }}" {% if request.GET.category == category.id|stringformat:'i' %}selected{% endif %}> <option value="{{ category.id }}" {% if request.GET.category == category.id|stringformat:'i' %}selected{% endif %}>
{{ category.name }} {{ category.name }}
</option> </option>
{% if category.children.all %} {% if category.available_children %}
{% for subcategory in category.children.all %} {% for subcategory in category.available_children %}
<option value="{{ subcategory.id }}" {% if request.GET.category == subcategory.id|stringformat:'i' %}selected{% endif %}> <option value="{{ subcategory.id }}" {% if request.GET.category == subcategory.id|stringformat:'i' %}selected{% endif %}>
&nbsp;&nbsp;&nbsp;{{ subcategory.name }} &nbsp;&nbsp;&nbsp;{{ subcategory.name }}
</option> </option>
@ -110,7 +110,7 @@
<div> <div>
<select class="form-select" id="consulting_partner" name="consulting_partner" @change="submitForm()"> <select class="form-select" id="consulting_partner" name="consulting_partner" @change="submitForm()">
<option value="">All Partners</option> <option value="">All Partners</option>
{% for partner in consulting_partners %} {% for partner in available_consulting_partners %}
<option value="{{ partner.id }}" {% if request.GET.consulting_partner == partner.id|stringformat:'i' %}selected{% endif %}> <option value="{{ partner.id }}" {% if request.GET.consulting_partner == partner.id|stringformat:'i' %}selected{% endif %}>
{{ partner.name }} {{ partner.name }}
</option> </option>
@ -127,7 +127,7 @@
<div> <div>
<select class="form-select" id="cloud_provider" name="cloud_provider" @change="submitForm()"> <select class="form-select" id="cloud_provider" name="cloud_provider" @change="submitForm()">
<option value="">All Providers</option> <option value="">All Providers</option>
{% for provider in cloud_providers %} {% for provider in available_cloud_providers %}
<option value="{{ provider.id }}" {% if request.GET.cloud_provider == provider.id|stringformat:'i' %}selected{% endif %}> <option value="{{ provider.id }}" {% if request.GET.cloud_provider == provider.id|stringformat:'i' %}selected{% endif %}>
{{ provider.name }} {{ provider.name }}
</option> </option>

View file

@ -9,55 +9,120 @@ from hub.services.models import (
def service_list(request): def service_list(request):
services = ( # Get basic filter parameters
Service.objects.filter(disable_listing=False) search_query = request.GET.get("search", "")
.order_by("-is_featured", "is_coming_soon", "name") category_id = request.GET.get("category", "")
.prefetch_related( consulting_partner_id = request.GET.get("consulting_partner", "")
"categories", cloud_provider_id = request.GET.get("cloud_provider", "")
"offerings",
"offerings__cloud_provider",
"offerings__plans",
"consulting_partners",
"external_links",
)
)
cloud_providers = CloudProvider.objects.all()
categories = Category.objects.filter(parent=None).prefetch_related("children")
# Handle category filter # Start with all active services
if request.GET.get("category"): # Filter out services with disable_listing=True
category_id = request.GET.get("category") services = Service.objects.filter(disable_listing=False)
category = get_object_or_404(Category, id=category_id)
subcategories = Category.objects.filter(parent=category) # Apply filters based on request parameters
if search_query:
services = services.filter( services = services.filter(
Q(categories=category) | Q(categories__in=subcategories) Q(name__icontains=search_query) | Q(description__icontains=search_query)
)
if category_id:
services = services.filter(categories__id=category_id)
if consulting_partner_id:
services = services.filter(consulting_partners__id=consulting_partner_id)
if cloud_provider_id:
# Filter through offerings instead of direct cloud_providers relation
services = services.filter(offerings__cloud_provider__id=cloud_provider_id)
# Get all available categories from filtered services
available_category_ids = services.values_list(
"categories__id", flat=True
).distinct() ).distinct()
available_categories = Category.objects.filter(
id__in=available_category_ids, parent=None
)
# Handle cloud provider filter # For each parent category, get available children
if request.GET.get("cloud_provider"): for category in available_categories:
provider_id = request.GET.get("cloud_provider") child_ids = (
services = services.filter(offerings__cloud_provider_id=provider_id).distinct() services.filter(categories__parent=category)
.values_list("categories__id", flat=True)
.distinct()
)
category.available_children = Category.objects.filter(id__in=child_ids)
# Handle consulting partner filter # Get available consulting partners from filtered services
if request.GET.get("consulting_partner"): # Excluding partners with disable_listing=True
partner_id = request.GET.get("consulting_partner") available_consulting_partner_ids = services.values_list(
services = services.filter(consulting_partners__id=partner_id).distinct() "consulting_partners__id", flat=True
# Handle search
if request.GET.get("search"):
query = request.GET.get("search")
services = services.filter(
Q(name__icontains=query)
| Q(description__icontains=query)
| Q(offerings__description__icontains=query)
).distinct() ).distinct()
available_consulting_partners = ConsultingPartner.objects.filter(
id__in=available_consulting_partner_ids, disable_listing=False
)
# Get available cloud providers from filtered services via offerings
# Excluding providers with disable_listing=True
available_cloud_provider_ids = services.values_list(
"offerings__cloud_provider__id", flat=True
).distinct()
available_cloud_providers = CloudProvider.objects.filter(
id__in=available_cloud_provider_ids, disable_listing=False
)
# For the current selection, we need to make sure we include the selected items
# even if they don't match other filters
if category_id:
try:
selected_category = Category.objects.get(id=category_id)
if selected_category.parent:
parent_category = selected_category.parent
if parent_category not in available_categories:
available_categories = list(available_categories)
available_categories.append(parent_category)
parent_category.available_children = [selected_category]
elif selected_category not in available_categories:
available_categories = list(available_categories)
available_categories.append(selected_category)
except Category.DoesNotExist:
pass
if consulting_partner_id:
try:
cp_id = int(consulting_partner_id)
if cp_id not in available_consulting_partner_ids:
selected_partner = ConsultingPartner.objects.get(id=cp_id)
available_consulting_partners = list(available_consulting_partners)
available_consulting_partners.append(selected_partner)
except (ValueError, ConsultingPartner.DoesNotExist):
pass
if cloud_provider_id:
try:
cp_id = int(cloud_provider_id)
if cp_id not in available_cloud_provider_ids:
selected_provider = CloudProvider.objects.get(id=cp_id)
available_cloud_providers = list(available_cloud_providers)
available_cloud_providers.append(selected_provider)
except (ValueError, CloudProvider.DoesNotExist):
pass
context = { context = {
"services": services, "services": services,
"cloud_providers": cloud_providers, "categories": Category.objects.filter(
"categories": categories, parent=None
"consulting_partners": ConsultingPartner.objects.all(), ), # Keep original for reference if needed
"consulting_partners": ConsultingPartner.objects.filter(
disable_listing=False
), # Keep original but filter out disabled
"cloud_providers": CloudProvider.objects.filter(
disable_listing=False
), # Keep original but filter out disabled
"available_categories": available_categories,
"available_consulting_partners": available_consulting_partners,
"available_cloud_providers": available_cloud_providers,
} }
return render(request, "services/service_list.html", context) return render(request, "services/service_list.html", context)