ixg_platform/apps/guides/views.py
ixgadmin d74f0814da Finish the wiki root move, zone map view and spec approval
- Follow home/user-guides/ through one GUIDE_PATH_PREFIX constant.
- Add a read-only Origin Zone detail view with the map as the main panel.
- Name due diligence explicitly and add its section headings.
- Add admin-only, four-eyes specification approval (portal and API).
- Empty the New-zone geometry placeholder instead of showing null.
2026-10-27 17:41:08 +00:00

66 lines
2.4 KiB
Python

from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.views.generic import DetailView, ListView
from .markdown import render_markdown
from .models import GUIDE_PATH_PREFIX, GuidePage, allowed_audiences
class GuideAccessMixin:
"""Scope the help centre by PORTAL first, then by role.
Being an admin does not mean seeing every guide in every portal: the buyer
portal lists buyer guides (the audience of its readers), the ops portal
lists ops guides, and the admin guides only appear in the ops portal for
admin/superuser accounts. See apps.guides.models.allowed_audiences.
"""
def get_portal(self):
return getattr(self.request.resolver_match, "namespace", None) or "portal"
def get_allowed_audiences(self):
user = self.request.user
return allowed_audiences(
self.get_portal(),
role=getattr(user, "role", None),
is_superuser=user.is_superuser,
)
def get_help_root(self):
return f"/{self.get_portal()}/help/"
class GuideIndexView(LoginRequiredMixin, GuideAccessMixin, ListView):
model = GuidePage
context_object_name = "guides"
def get_queryset(self):
return GuidePage.objects.filter(audience__in=self.get_allowed_audiences())
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx["help_root"] = self.get_help_root()
return ctx
class GuideDetailView(LoginRequiredMixin, GuideAccessMixin, DetailView):
model = GuidePage
# the templates read {{ guide.title }}; without this the object arrives as
# "object" and every guide detail page renders a blank browser title
context_object_name = "guide"
def get_object(self, queryset=None):
path = f"{GUIDE_PATH_PREFIX}{self.kwargs['page_path']}"
page = get_object_or_404(GuidePage, path=path)
if page.audience not in self.get_allowed_audiences():
raise Http404("This guide is not available in this portal.")
return page
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
help_root = self.get_help_root()
ctx["help_root"] = help_root
ctx["guide_html"] = render_markdown(self.object.content, self.object.path, help_root)
ctx["guides"] = GuidePage.objects.filter(audience__in=self.get_allowed_audiences())
return ctx