Features#
Frontend#
Pagination#
The blog index page comes with pagination support. You can set the number of posts per page using the POST_LIST_PAGINATION setting.
If there are more then 3 pages, there will be a “…” in the pagination. If there are more then 10 pages, there will be two “…” in the pagination.
Django-Admin#
The file sizes of an audio object are cached automatically. But for old audio objects there’s an admin action where you can update the file size cache for all associated audio files.

Blog#
Blog / NoIndex#
If you set the custom BooleanField field named noindex on a Blog-Page using the Wagtail or Django-Admin interface, the Page and all its subpages will be excluded from being indexed by search engines.
Video#
You can upload video files to the server and play them back in the browser.
Videos have a title a file field original pointing to the original video file, an image poster and a list of tags.
If no poster is given, the first frame of the video after one second is used as poster.
Audio#
You can upload audio files to the server and play them back in the browser.
Audio Models#
Audio files are represented by the Audio model. Audio files have a title, a subtitle, tags and four file fields pointing to the file in different audio formats:
m4a - AAC, works best on Apple/iOS devices
mp3 - MP3, works everywhere, but has no time index so the whole file has to be downloaded before playback can start
oga - OGG Vorbis, maybe remove this one because apple is now adding support for opus, too
opus - Opus, better quality per bitrate than all other formats, but not as well known as the others
Since podcast feeds only support one audio file per episode, there is one feed per audio format. The feeds are generated automatically and can be found at feed/podcast/<audio_format>/rss.xml.
Playback#
For playback of audio content Podlove Web Player version 4 is used.
Hint
Currently supported features:
Chapter marks
Download button
Templates / Themes#
You can choose different templates for the entire website or for specific blogs / podcasts. All users can select these templates from the Wagtail admin interface. Individual users can make their own template selections, which are stored in their session.
Plain HTML (plain) - This is just a plain HTML template without any CSS
Bootstrap 4 (bootstrap4) - This is a template that uses Bootstrap 4 and is currently the default template
Bootstrap 5 (bootstrap5) - This is a template that uses Bootstrap 5 and is the theme that I usually use for my own projects
Vue.js - This is a template that uses Vue.js and demonstrates how to combine an SPA frontend with django-cast
If you want to use your own templates, you can do so by overwriting the built-in templates or creating a new directory in your project’s templates directory and name it cast/{your_template_name}. Then you can create your own templates in this directory. After all of the following template names are added, you should be able to select your custom template in the Wagtail admin interface.
Important
This is the minimal list of templates that have to be implemented for a template named minimal:
cast/minimal/base.html
cast/minimal/blog_list_of_posts.html
cast/minimal/post.html
cast/minimal/post_body.html
cast/minimal/episode.html
cast/minimal/select_template.html
Hint
It’s only possible to create own template themes with template
loaders that implement the get_dirs method (FilesystemLoader,
CachedLoader). If you want to use a template loader that doesn’t
implement the get_dirs method, you have to add it to
settings.CAST_CUSTOM_THEMES
.
How to Change the Theme for the whole Site#
This setting can be found at settings > Template base directory:

There’s a context processor that adds the current template base directory aka theme to the context. For convenience it also adds the theme’s base template as a variable to the context to be able to extend it in non Wagtail templates.
Error Views#
If you want to use your own error views, you can do so by creating templates for each error code in your theme’s directory.
Hint
This is the list of templates that you can overwrite
cast/your_theme/404.html
cast/your_theme/500.html
cast/your_theme/400.html
cast/your_theme/403.html
cast/your_theme/403_csrf.html
Since now the error views need to know which theme to use, you have to overwrite the default error views in your project’s root URL-conf:
...
from cast.views import defaults as default_views_cast
handler404 = default_views_cast.page_not_found
handler500 = default_views_cast.server_error
handler400 = default_views_cast.bad_request
handler403 = default_views_cast.permission_denied
Setting the view for the 403_csrf error is a special case. You have to specify the view in your project’s settings:
...
# view handling csrf failures
CSRF_FAILURE_VIEW = "cast.views.defaults.csrf_failure"
How to Change the Theme for a Single Blog#
This setting can be found at pages > … > Blog:

How to Change the Theme for an Individual User#
The theme selection for an individual user is stored in request.session and does overwrite blog and site level theme settings.
JSON-Api#
You can get a list of selectable themes via the cast:api:theme-list endpoint. This endpoint will also show the currently selected theme. If you want to update the selected theme, you can do so via cast:api:theme-update.
Hypermedia#
The hypermedia endpoints for getting / setting the theme are:
cast:theme-list - List of all themes (the currently selected theme is marked)
cast:theme-update - Update the theme for the current user
Django-Admin Commands#
There are some management-commands bundled with django-cast. Most of them are dealing with the management of media files.
recalc_video_posters
: Recalculate the poster images for all videos.media_backup
: Backup media files from production to backup storage backend (requires Django >= 4.2).media_sizes
: Print the sizes of all media files stored in the production storage backend (requires Django >= 4.2).media_replace
: Replace files on production storage backend with versions from local file system (requires Django >= 4.2). This might be useful for videos for which you now have a better compressed version, but you don’t want to generate a new name.media_restore
: Restore media files from backup storage backend to production storage backend (requires Django >= 4.2).media_stale
: Print the paths of all media files stored in the production storage backend that are not referenced in the database (requires Django >= 4.2).
Comments#
You can enable / disable comments on app, blog and post-level. For app-level, there’s a global switch you can use in the settings. Blog and post models have a comments_enabled database field. They are set to
True
by default.Caveats#
The ajax-calls django-fluent-comments does depend on the availability of a full jquery version.
Comment Spam Filter#
There’s a simple Naive Bayes-based spam filter for comments built in. It’s not very smart, but it’s good enough to filter out most spam. It’s also very easy to train and very fast to run. And it’s only slightly above one hundred lines of pure Python code.
A comment is considered ham if it’s public and not removed. All other comments are considered spam. It’s possible to re-train the spam filter via a Django Admin action on the
SpamFilter
model. The precision, recall and F1 performance indicators are also shown in the admin interface.