Skip to content

2.3.4

Choose a tag to compare

@jonfroehlich jonfroehlich released this 13 Jun 15:04

2.3.4 — Performance, correctness, and hygiene

A focused pass on long-standing bugs and the publications/index page perf cliff. No breaking changes — drop-in upgrade from 2.3.2. 49 unit tests now pass (up from 0 at the start of the pass).

⚡ Performance

  • /publications/ is ~8× faster end-to-end. Added prefetch_related('authors', 'projects', 'keywords') to the Publication queryset across /publications/, /, /project/<n>/, and /member/<n>/. The snippet loops pub.authors.all / pub.projects.all / pub.keywords.all per row, so the prefetch eliminates the bulk of the N+1. Measured locally: 617 queries / 275.83 ms → 60 queries / 35 ms. (d4f6d65)
  • Talk and Video pages also faster via the same select_related + prefetch_related shape across index/project/member views. Index: 348 → 154 queries / 174 → 104 ms. Project page: 85 → 63 queries / 71 → 39 ms. (1cae31c)
  • Thumbnails now lazy-load. loading="lazy" added to all 9 artifact-thumbnail <img> tags in display_pub_snippet.html and display_talk_snippet.html. Below-the-fold images defer until scrolled into view. Particularly noticeable on slow mobile networks. (a51d812)

🐛 Bug fixes

  • serve_pdf no longer crashes on duplicate substring matches and no longer enables PDF-filename enumeration. Replaced Publication.objects.get(pdf_file__icontains=filename) with filter(pdf_file__iendswith=filename).first(). Preserves the fuzzy difflib fallback for stale external links (#1173). (f78fc14)
  • News pages with deleted authors no longer crash. News.author is null=True, on_delete=SET_NULL. Previously the news_item view raised AttributeError and the news_listing template raised NoReverseMatch whenever a News row's author had been removed. Both call sites guarded. (1c0d6c0)
  • delete_unused_files no longer crashes on artifacts with no PDF or thumbnail. Three call sites guarded (talk PDF, pub PDF, pub thumbnail), matching the existing poster-branch pattern (#1254). (202b1bb)
  • views/member.py MultipleObjectsReturned handler now references a real field. The fallback used order_by('-modified_date') which doesn't exist on Person; switched to -bio_datetime_modified (#1254). (202b1bb)
  • Artifact.do_filenames_need_updating checks the correct fields. The raw_file and thumbnail branches were both comparing pdf_file.name (copy-paste bug); each now checks its own field. (c7abcf7)
  • News.save() slug-collision loop excludes self. Admin-cleared slugs no longer bump unnecessarily on re-save. (c7abcf7)
  • Person.save() no longer leaks file descriptors when assigning the Star Wars fallback image — wrapped in try/finally that closes after super().save() reads the file. (c7abcf7)

🧹 Hygiene

  • Production file-log level is now INFO instead of DEBUG. The file handler in settings.py is conditional on DEBUG — local dev keeps verbose file logs; production logs are much smaller and no longer expose per-request URLs or _logger.debug payloads at /logs/debug.log. (~75 MB of stale rotated debug.log* files in ~/ml-www-prod were also cleaned up manually.) (31f2b4f)
  • Stray print() statements removed from models/projectils/ml_utils.py. (14da008)
  • Broken _logger.debug payload fixed in views/people.py:62 — the second positional arg was being silently dropped. (14da008)
  • Duplicate Coalesce import removed from models/personn models/project_role.py:88` per PEP 8 (#1254). (f0d44c1)
  • Dead code removed: get_closest_filename_from_filesystem helper in serve_pdf.py. (f78fc14)

🧪 Tests

The test suite went from effectively empty to 49 unit tests covering BibTeX citation, get_current_member_count, Artifact.do_filenames_need_updating, serve_pdf paths, plu_biocoverage. AllSimpleTestCase` — no DB setup required,runs in <100 ms.

🛠 Known follow-ups (not in this release)

  • Production-side Apache exemption for /media/publications/ (#1173) — the serve_pdf view's code is now safe to expose, but Apache on production still serves /media/publications/* directly. The test serve IT in Dec 2025; the prod-side ask is in flight.
  • /logs/ exposure design check — currently public by design per docs/DEPLOYMENT.md. Open question whether to add an IP allowlist or basic auth; not load-bearing since prod logs are now INFO-only.
  • DB-touching test infrastructure — would unlock assertNumQueries regression tests for the perf wins and view-level integration tests for the null-guard logic.

Full diff: https://github.com/makeabilitylab/makeabilityl.4