from django.http import Http404 from django.shortcuts import get_object_or_404 from django.urls import reverse from django.views.generic import DetailView, ListView, TemplateView from .models import MainProduct, ProductVideo, SubProduct VIDEO_PREVIEW_LIMIT = 3 VIDEO_ARCHIVE_PAGE_SIZE = 6 def _product_video_preview(queryset, archive_url): total = queryset.count() return { "product_videos": queryset[:VIDEO_PREVIEW_LIMIT], "videos_total_count": total, "videos_archive_url": archive_url if total > VIDEO_PREVIEW_LIMIT else "", } class ProductOverviewView(ListView): model = MainProduct template_name = "products/overview.html" context_object_name = "main_products" queryset = MainProduct.objects.filter(is_active=True).prefetch_related( "sub_products", "people" ) class MainProductDetailView(DetailView): model = MainProduct template_name = "products/main_detail.html" context_object_name = "main_product" slug_url_kwarg = "main_slug" queryset = MainProduct.objects.filter(is_active=True).prefetch_related( "sub_products", "people" ) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["articles"] = self.object.articles.prefetch_related( "sections", "citations", "people" ).all() videos = self.object.videos.filter(is_active=True).order_by("order", "pk") context.update( _product_video_preview( videos, reverse( "products:main_product_videos", kwargs={"main_slug": self.object.slug}, ), ) ) return context class SubProductDetailView(TemplateView): template_name = "products/sub_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) main_product = get_object_or_404( MainProduct, slug=self.kwargs["main_slug"], is_active=True, ) sub_product = get_object_or_404( SubProduct.objects.prefetch_related("people"), slug=self.kwargs["sub_slug"], main_product=main_product, is_active=True, ) context["main_product"] = main_product context["sub_product"] = sub_product context["articles"] = sub_product.articles.prefetch_related( "sections", "citations", "people" ).all() videos = sub_product.videos.filter(is_active=True).order_by("order", "pk") context.update( _product_video_preview( videos, reverse( "products:sub_product_videos", kwargs={ "main_slug": main_product.slug, "sub_slug": sub_product.slug, }, ), ) ) context["siblings"] = ( SubProduct.objects.filter(main_product=main_product, is_active=True) .exclude(pk=sub_product.pk) .order_by("order", "name") ) return context class ProductVideoArchiveView(ListView): model = ProductVideo template_name = "videos/archive.html" context_object_name = "videos" paginate_by = VIDEO_ARCHIVE_PAGE_SIZE def get_parent(self): main_product = get_object_or_404( MainProduct, slug=self.kwargs["main_slug"], is_active=True, ) sub_slug = self.kwargs.get("sub_slug") if sub_slug: return get_object_or_404( SubProduct, slug=sub_slug, main_product=main_product, is_active=True, ) return main_product def get_queryset(self): self.parent_object = self.get_parent() return self.parent_object.videos.filter(is_active=True).order_by("order", "pk") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update( { "library_title": f"{self.parent_object.name} videos", "library_description": ( "Tutorials, demonstrations, and technical guides." ), "library_back_url": self.parent_object.get_absolute_url(), "library_back_label": f"Back to {self.parent_object.name}", "pagination_range": context["paginator"].get_elided_page_range( context["page_obj"].number ), } ) return context