from django.shortcuts import render, get_object_or_404 from django.db.models import Q from hub.services.models import ( Service, ConsultingPartner, CloudProvider, Category, ) def service_list(request): # Get basic filter parameters search_query = request.GET.get("search", "") category_id = request.GET.get("category", "") consulting_partner_id = request.GET.get("consulting_partner", "") cloud_provider_id = request.GET.get("cloud_provider", "") # Start with all active services # Filter out services with disable_listing=True all_services = Service.objects.filter(disable_listing=False) services = all_services # Apply filters based on request parameters if search_query: services = services.filter( 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) # Order services: featured first, then regular services, then coming soon services = services.order_by( "-is_featured", # Featured first (True before False) "is_coming_soon", # Coming soon last (False before True) "name", # Alphabetically within each group ) # Create base querysets for each filter type that apply all OTHER current filters # This way, each filter shows options that would return results if selected # For category filter options, apply all other filters except category category_filter_base = all_services if search_query: category_filter_base = category_filter_base.filter( Q(name__icontains=search_query) | Q(description__icontains=search_query) ) if consulting_partner_id: category_filter_base = category_filter_base.filter( consulting_partners__id=consulting_partner_id ) if cloud_provider_id: category_filter_base = category_filter_base.filter( offerings__cloud_provider__id=cloud_provider_id ) # For consulting partner filter options, apply all other filters except consulting_partner cp_filter_base = all_services if search_query: cp_filter_base = cp_filter_base.filter( Q(name__icontains=search_query) | Q(description__icontains=search_query) ) if category_id: cp_filter_base = cp_filter_base.filter(categories__id=category_id) if cloud_provider_id: cp_filter_base = cp_filter_base.filter( offerings__cloud_provider__id=cloud_provider_id ) # For cloud provider filter options, apply all other filters except cloud_provider cloud_filter_base = all_services if search_query: cloud_filter_base = cloud_filter_base.filter( Q(name__icontains=search_query) | Q(description__icontains=search_query) ) if category_id: cloud_filter_base = cloud_filter_base.filter(categories__id=category_id) if consulting_partner_id: cloud_filter_base = cloud_filter_base.filter( consulting_partners__id=consulting_partner_id ) # Get available categories that would return results if selected available_parent_categories = Category.objects.filter( parent=None, id__in=category_filter_base.values_list( "categories__parent__id", flat=True ).distinct(), ).distinct() # Add categories that are direct matches (not children) direct_categories = Category.objects.filter( parent=None, id__in=category_filter_base.values_list("categories__id", flat=True).distinct(), ).distinct() available_parent_categories = ( available_parent_categories | direct_categories ).distinct() # For each parent category, get available children for parent_category in available_parent_categories: parent_category.available_children = Category.objects.filter( parent=parent_category, id__in=category_filter_base.values_list( "categories__id", flat=True ).distinct(), ).distinct() # Get available consulting partners and cloud providers that would return results if selected available_consulting_partners = ConsultingPartner.objects.filter( disable_listing=False, id__in=cp_filter_base.values_list( "consulting_partners__id", flat=True ).distinct(), ).distinct() available_cloud_providers = CloudProvider.objects.filter( disable_listing=False, id__in=cloud_filter_base.values_list( "offerings__cloud_provider__id", flat=True ).distinct(), ).distinct() context = { "services": services, "available_categories": available_parent_categories, "available_consulting_partners": available_consulting_partners, "available_cloud_providers": available_cloud_providers, "search_query": search_query, } return render(request, "services/service_list.html", context) def service_detail(request, slug): service = get_object_or_404( Service.objects.prefetch_related( "categories", "offerings", "offerings__cloud_provider", "offerings__plans", "consulting_partners", "external_links", ), slug=slug, ) context = { "service": service, } return render(request, "services/service_detail.html", context)