From 08c96e904aa29c3aa9c4f07fbfefc18f2dfd1dde Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Mon, 29 Dec 2025 13:51:41 +0330 Subject: [PATCH] admin fields titles and side bars changed base on url --- config/settings/base.py | 64 ++++++++++++++++++++++++++++++++++++----- utils/admin.py | 41 +++++++++++++++++++++----- 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 0eba77c..e129d1d 100755 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -314,12 +314,12 @@ LOGIN_REDIRECT_URL = reverse_lazy("admin.index") ###################################################################### # Unfold ###################################################################### -from utils.admin import admin_url_generator +from utils.admin import admin_url_generator , is_dovoodi_panel , is_main_panel UNFOLD = { - "SITE_TITLE": _("Imam Jawad Admin"), - "SITE_HEADER": _("Imam Jawad Admin"), - "SITE_SUBHEADER": _("Imam Jawad Online School"), + # "SITE_TITLE": _("Imam Jawad Admin"), + # "SITE_HEADER": _("Imam Jawad Admin"), + # "SITE_SUBHEADER": _("Imam Jawad Online School"), "SITE_DROPDOWN": [ { "icon": "diamond", @@ -612,7 +612,7 @@ UNFOLD = { "title": _("Students"), "icon": "school", "link": lambda request: admin_url_generator(request, "account_studentuser_changelist"), - "permission": lambda request: request.user.is_staff, + "permission": is_main_panel, }, ] @@ -624,7 +624,7 @@ UNFOLD = { "title": _("Professors"), "icon": "person_book", "link": lambda request: admin_url_generator(request, "account_professoruser_changelist"), - "permission": lambda request: request.user.is_staff, + "permission": is_main_panel, }, ] @@ -636,7 +636,7 @@ UNFOLD = { "title": _("Calender"), "icon": "calendar_today", "link": lambda request: admin_url_generator(request, "dobodbi_calendar_calendaroccasions_changelist"), - "permission": lambda request: request.user.is_staff, + "permission": is_dovoodi_panel, }, ], }, @@ -644,51 +644,61 @@ UNFOLD = { "title": _("Courses"), "collapsible": True, "separator": True, + "permission":is_main_panel, "items": [ { "title": _("Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "course_coursecategory_changelist"), + "permission":is_main_panel, }, { "title": _("Courses"), "icon": "school", "link": lambda request: admin_url_generator(request, "course_course_changelist"), + "permission":is_main_panel, }, { "title": _("Lessons"), "icon": "menu_book", "link": lambda request: admin_url_generator(request, "course_lesson_changelist"), + "permission":is_main_panel, }, { "title": _("Attachments"), "icon": "attach_file", "link": lambda request: admin_url_generator(request, "course_attachment_changelist"), + "permission":is_main_panel, }, { "title": _("Glossary"), "icon": "book", "link": lambda request: admin_url_generator(request, "course_glossary_changelist"), + "permission":is_main_panel, }, { "title": _("Live Sessions"), "icon": "video_call", "link": lambda request: admin_url_generator(request, "course_courselivesession_changelist"), + "permission":is_main_panel, }, { "title": _("Session Users"), "icon": "groups", "link": lambda request: admin_url_generator(request, "course_livesessionuser_changelist"), + "permission":is_main_panel, }, { "title": _("Session Recordings"), "icon": "play_circle", "link": lambda request: admin_url_generator(request, "course_livesessionrecording_changelist"), + "permission":is_main_panel, }, { "title": _("Certificates"), "icon": "workspace_premium", "link": lambda request: admin_url_generator(request, "certificate_certificate_changelist"), + "permission":is_main_panel, }, ] }, @@ -696,16 +706,19 @@ UNFOLD = { "title": _("Quizzes"), "collapsible": True, "separator": True, + "permission":is_main_panel, "items": [ { "title": _("Quizzes"), "icon": "quiz", "link": lambda request: admin_url_generator(request, "quiz_quiz_changelist"), + "permission":is_main_panel, }, { "title": _("Quiz Participants"), "icon": "group", "link": lambda request: admin_url_generator(request, "quiz_quizparticipant_changelist"), + "permission":is_main_panel, }, ] }, @@ -718,6 +731,7 @@ UNFOLD = { "title": _("Transactions"), "icon": "payments", "link": lambda request: admin_url_generator(request, "transaction_transactionparticipant_changelist"), + "permission":is_main_panel, }, ] }, @@ -725,21 +739,25 @@ UNFOLD = { "title": _("Libraries"), "collapsible": True, "separator": True, + "permission":is_dovoodi_panel, "items": [ { "title": _("Books"), "icon": "menu_book", "link": lambda request: admin_url_generator(request, "library_book_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "library_category_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Collections"), "icon": "view_module", "link": lambda request: admin_url_generator(request, "library_pinnedbookcollection_changelist"), + "permission":is_dovoodi_panel, }, ] }, @@ -747,26 +765,31 @@ UNFOLD = { "title": _("Videos"), "collapsible": True, "separator": True, + "permission":is_dovoodi_panel, "items": [ { "title": _("Videos"), "icon": "live_tv", "link": lambda request: admin_url_generator(request, "video_video_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "video_videocategory_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Collections"), "icon": "view_module", "link": lambda request: admin_url_generator(request, "video_pinnedvideocollection_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Playlists"), "icon": "playlist_play", "link": lambda request: admin_url_generator(request, "video_videoplaylist_changelist"), + "permission":is_dovoodi_panel, # "active": lambda request: "video/videoplaylist" in request.path, }, @@ -776,16 +799,19 @@ UNFOLD = { "title": _("Blog"), "collapsible": True, "separator": True, + "permission":is_main_panel, "items": [ { "title": _("Comments"), "icon": "comment", "link": lambda request: admin_url_generator(request, "api_comment_changelist"), + "permission":is_main_panel, }, { "title": _("Blogs"), "icon": "article", "link": lambda request: admin_url_generator(request, "blog_blog_changelist"), + "permission":is_main_panel, }, ] }, @@ -803,31 +829,37 @@ UNFOLD = { "title": _("Articles"), "collapsible": True, "separator": True, + "permission":is_dovoodi_panel, "items": [ { "title": _("Articles"), "icon": "article", "link": lambda request: admin_url_generator(request, "article_article_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "article_articlecategory_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Pinned Collections"), "icon": "collections_bookmark", "link": lambda request: admin_url_generator(request, "article_pinnedarticlecollection_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Regular Collections"), "icon": "view_module", "link": lambda request: admin_url_generator(request, "article_middlearticlecollection_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Article Contents"), "icon": "text_snippet", "link": lambda request: admin_url_generator(request, "article_articlecontent_changelist"), + "permission":is_dovoodi_panel, }, ] }, @@ -835,36 +867,43 @@ UNFOLD = { "title": _("Podcasts"), "collapsible": True, "separator": True, + "permission":is_dovoodi_panel, "items": [ { "title": _("Podcasts"), "icon": "headset", "link": lambda request: admin_url_generator(request, "podcast_podcast_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "podcast_podcastcategory_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Pinned Collections"), "icon": "collections_bookmark", "link": lambda request: admin_url_generator(request, "podcast_pinnedpodcastcollection_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Regular Collections"), "icon": "view_module", "link": lambda request: admin_url_generator(request, "podcast_middlepodcastcollection_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Playlists"), "icon": "playlist_play", "link": lambda request: admin_url_generator(request, "podcast_podcastplaylist_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("User Playlists"), "icon": "person_add", "link": lambda request: admin_url_generator(request, "podcast_userplaylist_changelist"), + "permission":is_dovoodi_panel, }, ] }, @@ -872,11 +911,13 @@ UNFOLD = { "title": _("Chats"), "collapsible": True, "separator": True, + "permission":is_main_panel, "items": [ { "title": _("Chat Rooms"), "icon": "forum", "link": lambda request: admin_url_generator(request, "chat_roommessage_changelist"), + "permission":is_main_panel, }, # { # "title": _("Chat Messages"), @@ -894,46 +935,55 @@ UNFOLD = { "title": _("Hadis"), "collapsible": True, "separator": True, + "permission":is_dovoodi_panel, "items": [ { "title": _("Hadis Sects"), "icon": "account_tree", "link": lambda request: admin_url_generator(request, "hadis_hadissect_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis Categories"), "icon": "category", "link": lambda request: admin_url_generator(request, "hadis_hadiscategory_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis"), "icon": "format_quote", "link": lambda request: admin_url_generator(request, "hadis_hadis_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis References"), "icon": "link", "link": lambda request: admin_url_generator(request, "hadis_hadisreference_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis Tags"), "icon": "label", "link": lambda request: admin_url_generator(request, "hadis_hadistag_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis Status"), "icon": "flag", "link": lambda request: admin_url_generator(request, "hadis_hadisstatus_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Transmitters"), "icon": "person", "link": lambda request: admin_url_generator(request, "hadis_transmitters_changelist"), + "permission":is_dovoodi_panel, }, { "title": _("Hadis Transmitters"), "icon": "group", "link": lambda request: admin_url_generator(request, "hadis_hadistransmitter_changelist"), + "permission":is_dovoodi_panel, }, ] }, diff --git a/utils/admin.py b/utils/admin.py index 24043ba..a2cacfe 100644 --- a/utils/admin.py +++ b/utils/admin.py @@ -17,27 +17,37 @@ from unfold.sites import UnfoldAdminSite # 1. Helper Functions # --------------------------------------------------------- +def is_dovoodi_panel(request): + """ + Returns True if the user is accessing the Dovoodi admin panel. + Checks if '/dovoodi/' exists anywhere in the path to handle i18n prefixes + (e.g., /en/dovoodi/admin, /fa/dovoodi/admin). + """ + return '/dovoodi/' in request.path + +def is_main_panel(request): + """Returns True if the user is accessing the Main (Imam Javad) admin panel.""" + return not is_dovoodi_panel(request) + def admin_url_generator(request, url_name): """ Dynamically generates admin URLs based on the current active panel. Usage in settings.py: lambda request: admin_url_generator(request, "app_model_changelist") """ - # 1. Determine the current namespace based on the URL path - if request.path.startswith('/en/dovoodi/') or request.path.startswith('/dovoodi/'): + # 1. Determine the current namespace using the robust check + if is_dovoodi_panel(request): namespace = 'dovoodi_admin' else: # Default to the main admin namespace = 'imam_javad_admin' - # 2. Construct the view name (e.g., "imam_javad_admin:account_user_changelist") + # 2. Construct the view name full_view_name = f"{namespace}:{url_name}" # 3. Resolve the URL try: return reverse(full_view_name) except Exception: - # If the model isn't registered in this specific admin, return a dead link - # to prevent the whole page from crashing. return "#" def dashboard_callback(request, context): @@ -78,6 +88,7 @@ class FormulaAdminSite(UnfoldAdminSite): site_header = "Imam Javad Admin" site_title = "Imam Javad" index_title = "System Administration" + site_subheader = "Imam Javad School" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -89,6 +100,7 @@ class DovoodiAdminSite(UnfoldAdminSite): site_header = "Dovoodi Admin" site_title = "Dovoodi" index_title = "System Administration" + site_subheader = "Dovodbi Application" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -100,11 +112,16 @@ class AdminSitePlaceholder(UnfoldAdminSite): """Placeholder that behaves like an admin site until Django is fully loaded""" def __init__(self, site_class, name): - # Initialize with minimal setup to avoid circular imports + # 1. Store config for lazy loading self._site_class = site_class self._name = name self._real_instance = None - # Don't call super().__init__() here to avoid circular imports + + # 2. THE FIX: Copy visual attributes immediately so Templates see them! + self.site_header = getattr(site_class, 'site_header', 'Django Admin') + self.site_title = getattr(site_class, 'site_title', 'Django Site') + self.index_title = getattr(site_class, 'index_title', 'Site Administration') + self.site_subheader = getattr(site_class, 'site_subheader', '') def _get_real_instance(self): if self._real_instance is None: @@ -117,6 +134,16 @@ class AdminSitePlaceholder(UnfoldAdminSite): def __call__(self, *args, **kwargs): return self._get_real_instance()(*args, **kwargs) + def get_urls(self): + return self._get_real_instance().get_urls() + + @property + def urls(self): + return self._get_real_instance().urls + + def each_context(self, request): + return self._get_real_instance().each_context(request) + # Create placeholder instances project_admin_site = AdminSitePlaceholder(FormulaAdminSite, 'imam_javad_admin') dovoodi_admin_site = AdminSitePlaceholder(DovoodiAdminSite, 'dovoodi_admin')