learning-website-django1-6 Exercise 3: Check the Navigation Against the Real Pages ================================================================================= The tests use small made-up pages. Check the navigation against the real imported content (Chapter 4's database), and count the queries a page costs. Save as nav_stats.py in the project folder and run it: """nav_stats.py: check the derived navigation against the real, imported pages. Run from the project folder.""" import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.dev") import django django.setup() from django.core.cache import cache from django.db import connection from django.test import Client from django.test.utils import CaptureQueriesContext from apps.content.models import Page from apps.navigation.menus import site_menu from config.sites_config import SIDEBAR_ROUTES, SITES cache.clear() top_folders = {p.split("/")[0] for p in Page.objects.values_list("path", flat=True)} print(f"top-level folders that have imported pages: {len(top_folders)}") in_menu = {} for site in SITES: items = site_menu(site) for item in items: in_menu.setdefault(item["folder"], []).append(site) print(f" {site:<15}{len(items):>3} entries: {', '.join(i['label'] for i in items[:4])}{' ...' if len(items) > 4 else ''}") print("folders with pages but in NO site menu:", sorted(f for f in top_folders if f not in in_menu) or "none") print("folders in more than one menu:", {f: s for f, s in in_menu.items() if len(s) > 1} or "none (the sidebar is one folder but each site shows its own part)") print("folders in the site map with no pages (so no menu entry):", sorted(f for info in SITES.values() for f in info["folders"] if f not in top_folders) or "none") client = Client(HTTP_HOST="languages.localhost") chapter = "/hungary/hungarian-basic-3/hungarian_basic_conversation_3_5/" client.get(chapter) # warm the menu cache with CaptureQueriesContext(connection) as q: r = client.get(chapter) print(f"a chapter page: HTTP {r.status_code}, {len(q)} database queries (menus come from the cache)") with CaptureQueriesContext(connection) as q: r = client.get("/hungary/hungarian-basic-3/") print(f"its course listing: HTTP {r.status_code}, {len(q)} queries") with CaptureQueriesContext(connection) as q: r = client.get("/hungary/") print(f"the Hungary folder listing: HTTP {r.status_code}, {len(q)} queries") sys_client = Client(HTTP_HOST="systems.localhost") r = sys_client.get("/sidebar/") print(f"systems /sidebar/: HTTP {r.status_code}; languages /sidebar/: HTTP {client.get('/sidebar/').status_code}") python nav_stats.py Output (checked by running it on the imported content): top-level folders that have imported pages: 49 languages 5 entries: France, Germany, Hungary, Japan ... webdevelopment 4 entries: Web Development, Web Platforms, Web Servers, Sidebar programming 12 entries: Programming, Software Development, Maths for Programmers, Retro Computing ... systems 9 entries: Linux, Operating Systems, Networking, Cloud and DevOps ... ai 3 entries: AI, Data Science and ML, Sidebar humanities 13 entries: History, Politics, Philosophy, Art History ... lifeskills 5 entries: Practical Life Skills, Cookery, Freelancing and Business Skills, YouTube ... creative 3 entries: Creative and Design Tools, Audio Video Production, Office and Productivity Software folders with pages but in NO site menu: none folders in more than one menu: {'sidebar': ['webdevelopment', 'programming', 'systems', 'ai', 'humanities', 'lifeskills']} folders in the site map with no pages (so no menu entry): none a chapter page: HTTP 200, 4 database queries (menus come from the cache) its course listing: HTTP 200, 4 queries the Hungary folder listing: HTTP 200, 4 queries systems /sidebar/: HTTP 200; languages /sidebar/: HTTP 404 What it shows ------------- - All 49 top-level folders that have pages appear in a site menu. The live site's hand-written menu was missing 13 of them (Learning Website: Framework & Architecture 5). Derived menus cannot drift. - No folder in the site map is empty, and none is in two menus. The sidebar is one folder but appears in six sites' menus, each showing only its own subjects. The languages site has no sidebar entry and /sidebar/ is a 404 there. - A chapter page costs 4 queries, and each listing 4: the page itself, the breadcrumb's course names, the two neighbours. The menus cost none, because they come from the cache. - The labels read "Data Science and ML" and "Cloud and DevOps", fixing the live site's "Data Science And Ml" and "Cloud And Devops". Looking at it ------------- Headless Chrome screenshots of the course listing (Hungarian Basic Conversation 3) and of the Linux folder were looked at. The listing shows the global bar with Languages in the accent colour, the site menu with Hungary underlined, the breadcrumb Languages > Hungary > Hungarian Basic Conversation 3, and the twelve chapters numbered in order. Not verified: PHONE WIDTH. A headless screenshot at 390 pixels wide did not look like a true phone layout (the page appeared to be laid out about 500 pixels wide and cropped, so a menu item looked cut off). Chrome seems to impose a minimum window width in headless mode. Check the narrow layout in a real browser with its device toolbar before relying on it. The global bar scrolls sideways and the site menu wraps by design. WHY THIS WORKS AS AN ANSWER --------------------------- The strongest claim about derived navigation, "nothing can be missing", is one a script can test on the real data, and the query count is the number to watch as the site grows. Saying what the screenshot could not show is part of the result.