import random from django.db.models import Prefetch from django.http import JsonResponse from django.shortcuts import render from django.views import View from django.views.generic import DetailView, ListView, TemplateView from apps.products.models import MainProduct, SubProduct from apps.projects.models import ProjectBrief from .forms import ContactForm from .models import ( AboutSection, ContactSubmission, ContactSubmissionAttachment, CustomPage, FAQEntry, HeroSection, HomepageSection, PageVideo, ) def _homepage_products_catalog_queryset(): return ( MainProduct.objects.filter(is_active=True) .prefetch_related( Prefetch( "sub_products", queryset=SubProduct.objects.filter(is_active=True).order_by("order", "name"), ) ) .order_by("order", "name") ) class HomeView(TemplateView): template_name = "pages/home.html" def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx["hero"] = HeroSection.objects.first() ctx["homepage_sections"] = ( HomepageSection.objects.filter(is_active=True) .prefetch_related("items") .order_by("order") ) ctx["homepage_products"] = ( MainProduct.objects.filter(is_active=True, show_on_homepage=True) .order_by("homepage_order", "order") ) ctx["homepage_products_catalog"] = _homepage_products_catalog_queryset() ctx["website_project_briefs"] = ( ProjectBrief.objects.filter(show_on_website=True) .order_by("-submitted_at") ) return ctx class AboutView(TemplateView): template_name = "pages/about.html" def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx["about_sections"] = ( AboutSection.objects.filter(is_active=True) .prefetch_related("items") .order_by("order") ) return ctx class FAQView(ListView): model = FAQEntry template_name = "pages/faq.html" context_object_name = "faq_entries" queryset = FAQEntry.objects.filter(is_active=True) def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx["faq_videos"] = PageVideo.objects.filter( page=PageVideo.PAGE_FAQ, is_active=True, ).order_by("order") return ctx class ContactView(View): template_name = "pages/contact.html" def _new_captcha(self, request): a, b = random.randint(1, 9), random.randint(1, 9) request.session["captcha_answer"] = a + b return f"{a} + {b}" def get(self, request, *args, **kwargs): return render( request, self.template_name, { "form": ContactForm(), "captcha_question": self._new_captcha(request), "contact_videos": PageVideo.objects.filter( page=PageVideo.PAGE_CONTACT, is_active=True, ).order_by("order"), }, ) def post(self, request, *args, **kwargs): form = ContactForm( request.POST, file_list=request.FILES.getlist("attachments"), ) expected = request.session.get("captcha_answer") captcha_question = self._new_captcha(request) captcha_ok = False try: captcha_ok = int(request.POST.get("captcha_answer", "")) == expected except (ValueError, TypeError): pass if form.is_valid() and captcha_ok: submission = form.save() for uploaded_file, original_name in form.cleaned_data.get( "attachments", [] ): attachment = ContactSubmissionAttachment( submission=submission, original_filename=original_name, ) attachment.file.save(original_name, uploaded_file, save=True) return JsonResponse({"success": True}) errors: dict = {} if not captcha_ok: errors["captcha"] = ["Incorrect answer — please try again."] errors.update( {field: [str(e) for e in errs] for field, errs in form.errors.items()} ) return JsonResponse( {"success": False, "errors": errors, "captcha_question": captcha_question}, status=400, ) class CustomPageView(DetailView): model = CustomPage template_name = "pages/custom_page.html" context_object_name = "custom_page" slug_url_kwarg = "slug" def get_queryset(self): return CustomPage.objects.filter(is_published=True) def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx["page_sections"] = ( self.object.sections.filter(is_active=True) .prefetch_related("items") .order_by("order") ) ctx["homepage_products"] = ( MainProduct.objects.filter(is_active=True, show_on_homepage=True) .order_by("homepage_order", "order") ) ctx["homepage_products_catalog"] = _homepage_products_catalog_queryset() return ctx