0.2.54 (2026-03-09)¶
Added canonical repository class names:
PostQuerySnapshot,PostDetailContext,BlogIndexContext,FeedContext, andEpisodeFeedContext.Added canonical repository serialization APIs:
serialize_audio/deserialize_audio,serialize_video/deserialize_video,serialize_image/deserialize_image,serialize_blog/deserialize_blog,serialize_post/deserialize_post,serialize_episode/deserialize_episode, andserialize_transcript/deserialize_transcript.Breaking change: removed legacy repository class aliases
QuerysetData,PostDetailRepository,BlogIndexRepository,FeedRepository, andEpisodeFeedRepository.Breaking change: removed legacy serialization aliases
audio_to_dict,video_to_dict,image_to_dict,blog_to_dict/blog_from_data,post_to_dict,episode_to_dict, andtranscript_to_dict.Canonical names are now the only supported API surface for repository classes and serialization helpers.
Repository hardening pass: - removed dead PostQuerySnapshot.create_from_post_queryset(…, is_podcast=…) API surface and dead branch - fixed repository-layer import coupling (HtmxHttpRequest/PostFilterset) by moving to type-only/local imports - guarded add_site_raw SQL fallback for empty-site rows (fetchone() is None) - corrected media ID aliases to use set[int] - removed dead CastBlock type alias and Site package re-export - narrowed transcript exception handling to avoid masking AttributeError - added EpisodeFeedContext to model reference docs - removed duplicate URL computation in data_for_blog_cachable by serializing URL maps in add_queryset_data - fixed FeedContext.create_from_django_models to handle Site.find_for_request(request) is None
Secured media detail API authorization: - VideoDetailView and AudioDetailView now scope object lookup to request.user, preventing cross-user retrieve/delete. - Added regression tests for owner and non-owner GET/DELETE behavior, including unauthenticated DELETE responses.
Hardened styleguide helper account setup: - the styleguide user is now forced to set_unusable_password(), is_active=False, and removed from the Moderators group. - added regression tests to guarantee the styleguide account remains non-login and de-privileged.
Fixed request-state leakage in
Post.get_context()by avoiding mutation of the page instance (owner/page_url); request-specific values are now applied to a context-local page object instead.Fixed rich-text internal page-link cache isolation by replacing the process-global
PageLinkHandlerWithCache.cachedict with context-local storage, preventing cross-request/thread cache leakage during concurrent rendering while preserving existing link-resolution behavior.Hardened
Audio.save()persistence flow by wrapping enrichment in a database transaction and collapsing up to three writes into one initial save plus at most one targeted follow-up update, reducing partial-update risk while preserving duration and file-size metadata behavior.Fixed
Video._create_poster()file-handle lifecycle by closing themkstempdescriptor, context-managing poster file reads, and always cleaning up the temporary poster file; added regression tests for success, save-failure, and missing-temp-file cleanup paths.Fixed stale settings reads in
cast.appsettingsandcast.renditionsby resolving settings at runtime so@override_settingschanges are respected after module import.Aligned test
INSTALLED_APPSwith shippedCAST_APPSby reusingcast.apps.CAST_APPS, ensuringrest_framework,django_htmx, andwagtail.api.v2are present in tests and adding regression checks to prevent future app-list drift.Hardened
media_replacewith safe defaults: it now requires explicit--yesconfirmation for destructive writes, supports non-destructive previews via--dry-run, and reports per-file operations plus summary counts for planned/replaced/skipped/errors.Added new Django system checks for configuration safety:
cast.E002validatescast.comments.apps.CastCommentsConfigis listed beforedjango_commentsinINSTALLED_APPS, andcast.E003validates all middleware listed incast.apps.CAST_MIDDLEWAREare present insettings.MIDDLEWARE.Hardened
select_themePOST redirects by validatingnextwithurl_has_allowed_host_and_schemeagainst the current host/scheme and falling back to the local select-theme URL whennextis empty or unsafe.Fixed runtime comment setting lookups so
cast.commentsform/helper CSS and exclude-field settings are resolved lazily instead of freezing at import time.Fixed the comments fallback
CRISPY_TEMPLATE_PACKdefault tobootstrap4so AJAX validation errors still render when projects rely on django-cast’s built-in crispy setup without redefining that setting.Pinned the CI
uvinstallation step to0.10.2for more predictable workflow behavior.Fixed Python 3.11-3.13 compatibility for
Postmodel imports by replacing a runtime-evaluated"Blog" | Noneannotation withOptional["Blog"].Typed Django system check callables in
cast.checkssouv run mypyno longer emitsannotation-uncheckednotes during the release gate.Fixed migration
0063_gallery_signaturefor current Django versions by providing an explicitchunk_sizewhen iterating a prefetched queryset.Hardened
recalc_video_posterswith progress output, per-video error handling, and completion summaries so one broken video no longer aborts the entire command.Replaced mutable class-level fallback repository dicts in
blocks.pywith per-instance mappings.Reduced settings drift by making
tests.settingsimport shared defaults fromcast.settingsand keep only explicit test-specific overrides.Hardened
media_staleso cleanup now preserves liveAudioandTranscriptassets instead of misclassifying them as stale.Made the optional theme-template contract more forgiving by falling back to
cast/plainwhen a discovered theme omitstranscript.htmlorgallery_modal.html.Added
just test-slowso contributors can run only the intentionally slower integration/dev-surface tests that complementjust test-fast.Restricted
GET /api/comment_training_data/to staff users so comment training exports are no longer exposed to arbitrary authenticated users.Made slug-based feed, transcript, and meta endpoints site-scoped so multisite installs resolve pages within the current site tree instead of failing on duplicate slugs. These lookups now intentionally stay limited to live pages.
Hardened
sync_renditions --blog-slugto raiseCommandErrorwhen a slug is missing or ambiguous instead of silently targeting the wrong blog.Fixed
Video.save()follow-up poster persistence soforce_insertandobjects.create()paths no longer trigger a duplicate insert.Hardened the gallery modal view to return a controlled 404 when the requested image was deleted after the page HTML was rendered.
Migration mapping (old -> new):
Removed |
Replacement |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|