1fromtypingimportTYPE_CHECKING 2 3fromplain.auth.viewsimportAuthViewMixin 4fromplain.urlsimportreverse 5fromplain.utilsimporttimezone 6fromplain.viewsimport( 7TemplateView, 8) 9 10from.registryimportregistry 11from.typesimportImg 12 13ifTYPE_CHECKING: 14from..cardsimportCard 15 16 17URL_NAMESPACE="admin" 18 19 20classAdminView(AuthViewMixin,TemplateView): 21admin_required=True 22 23title:str="" 24path:str="" 25description:str="" 26image:Img|None=None 27 28# Leave empty to hide from nav 29# 30# An explicit disabling of showing this url/page in the nav 31# which importantly effects the (future) recent pages list 32# so you can also use this for pages that can never be bookmarked 33nav_section="App" 34nav_title="" 35 36links:dict[str]={} 37 38parent_view_class:"AdminView"=None 39 40template_name="admin/page.html" 41cards:list["Card"]=[] 42 43defget_response(self): 44response=super().get_response() 45response.headers["Cache-Control"]=( 46"no-cache, no-store, must-revalidate, max-age=0" 47) 48returnresponse 49 50defget_template_context(self): 51context=super().get_template_context() 52context["title"]=self.get_title() 53context["image"]=self.get_image() 54context["slug"]=self.get_slug() 55context["description"]=self.get_description() 56context["links"]=self.get_links() 57context["parent_view_classes"]=self.get_parent_view_classes() 58context["admin_registry"]=registry 59context["cards"]=self.get_cards() 60context["render_card"]=lambdacard:card().render(self,self.request) 61context["time_zone"]=timezone.get_current_timezone_name() 62returncontext 63 64@classmethod 65defview_name(cls)->str: 66returnf"view_{cls.get_slug()}" 67 68@classmethod 69defget_slug(cls)->str: 70returnf"{cls.__module__}.{cls.__qualname__}".lower().replace(".","_") 71 72# Can actually use @classmethod, @staticmethod or regular method for these? 73defget_title(self)->str: 74returnself.title 75 76defget_image(self)->Img|None: 77returnself.image 78 79defget_description(self)->str: 80returnself.description 81 82@classmethod 83defget_path(cls)->str: 84returncls.path 85 86@classmethod 87defget_parent_view_classes(cls)->list["AdminView"]: 88parents=[] 89parent=cls.parent_view_class 90whileparent: 91parents.append(parent) 92parent=parent.parent_view_class 93returnparents 94 95@classmethod 96defget_nav_section(cls)->bool: 97ifnotcls.nav_section: 98return"" 99100ifcls.parent_view_class:101# Don't show child views by default102return""103104returncls.nav_section105106@classmethod107defget_nav_title(cls)->str:108ifcls.nav_title:109returncls.nav_title110111ifcls.title:112returncls.title113114raiseNotImplementedError(115f"Please set a title or nav_title on the {cls} class or implement get_nav_title()."116)117118@classmethod119defget_view_url(cls,obj=None)->str:120ifobj:121returnreverse(f"{URL_NAMESPACE}:"+cls.view_name(),pk=obj.pk)122else:123returnreverse(f"{URL_NAMESPACE}:"+cls.view_name())124125defget_links(self)->dict[str]:126returnself.links.copy()127128defget_cards(self):129returnself.cards.copy()