Development¶
This guide covers everything you need to know to contribute to django-cast development.
Planning Future Work¶
Planned work is tracked in the project backlog. Add or update backlog entries there instead of maintaining separate planned-work lists in the README or docs.
Development Environment Setup¶
Prerequisites¶
Before you begin, ensure you have the following installed:
Cloning the Repository¶
Start by forking and cloning the django-cast repository:
$ git clone git@github.com:your-username/django-cast.git
$ cd django-cast
$ git checkout develop
Note
Development happens on the develop branch. The main branch is reserved for stable releases.
Setting Up the Python Environment¶
Create a virtual environment and install all dependencies:
$ just install
# or directly: uv sync
This command will:
Create a virtual environment if one doesn’t exist
Install django-cast in editable mode
Install all development dependencies
Setting Up the JavaScript Environment¶
Navigate to the JavaScript directory and install dependencies:
$ cd javascript
$ npm install
Bootstrap5 Theme (Required for Example App)¶
The example app uses the Bootstrap5 theme, which lives in a sibling repo. Install it in editable mode:
$ uv pip install -e ../cast-bootstrap5
If cast-bootstrap5 is not available, the example app will fall back to the
built-in bootstrap4 theme.
Database Setup¶
Create and migrate the development database:
$ cd example
$ uv run python manage.py migrate
Bootstrap demo content (recommended after a clean DB rebuild):
$ uv run python scripts/bootstrap_example_data.py --reset-db
Note
This repository contains two manage.py entry points:
manage.py(repository root) defaults totests.settingsand is mainly used for running the test suite.example/manage.pyusesexample_site.settings.devand is intended for interactive development.
Running the Development Server¶
Django-cast is typically developed as an installed package in a separate project. For quick testing, you can use the example project:
$ cd example
$ uv run python manage.py runserver
Or start Django + both Vite dev servers together:
$ just dev
Note
just dev will skip the Bootstrap5 or cast-vue Vite servers if the sibling
repos (../cast-bootstrap5 or ../cast-vue) are missing, and the example
app will fall back to the built-in bootstrap4 theme.
For agent-friendly local workflow, you can also use:
$ just dev-tmux # create detached tmux session "cast-dev" (run again to attach)
$ just dev-status # quick health/status output
$ just dev-logs django # tail one service log
$ just dev-logs-dir # print current log directory
$ just dev-open # open http://localhost:8000
For JavaScript development with hot reloading:
$ cd javascript
$ npm run dev
For the Bootstrap5 theme assets (default theme), run its Vite dev server too:
$ cd ../cast-bootstrap5/javascript
$ npm run dev
If you have the optional cast-vue theme installed, run its Vite dev server
as well (see the cast-vue repository for details).
If you do not want to run Vite, set these environment variables to use the prebuilt manifests instead:
$ export CAST_VITE_DEV_MODE=0
$ export CAST_BOOTSTRAP5_VITE_DEV_MODE=0
$ export CAST_VUE_VITE_DEV_MODE=0
Note
Podcast pages (Podlove player) rely on the Vite dev server during local
development. Keep the relevant npm run dev process running while
testing podcast list/detail pages to ensure the player loads.
Styleguide¶
Use two different URLs during frontend verification. They serve different purposes.
Note
These dev-only routes are gated by CAST_ENABLE_DEV_TOOLS (or deprecated
CAST_ENABLE_STYLEGUIDE alias). If disabled, they return 404.
The styleguide route is still available, but the long-term direction is the
reference-site workflow (ensure_reference_site + real page checks).
Component preview route:
http://localhost:8000/cast/styleguide/
This renders seeded preview components for the active theme (cards, media blocks, comments, galleries, podcast snippets). It is the fastest way to inspect visual regressions in isolated sections.
Real list-page behavior route:
http://localhost:8000/styleguide-blog/
This is a real Wagtail blog index page. Use it for end-to-end checks of:
search query behavior (
?search=python)facet selection (
?date_facets=2026-02&tag_facets=django)filter + pagination/navigation interactions
Note
/styleguide-blog/ is created by the styleguide seeder. If it returns a
404, create/update reference content first:
$ just ensure-reference-site
Switch styleguide theme via query param:
http://localhost:8000/cast/styleguide/?theme=bootstrap4
If the requested theme does not provide styleguide templates, the view falls back to a built-in theme and shows a warning banner.
Theme comparison and screenshots¶
Compare themes side-by-side in the browser:
http://localhost:8000/cast/theme-compare/?path=/styleguide-blog/
Use Playwright helpers for screenshots and console-error checks:
$ just screenshot /styleguide-blog/ --theme bootstrap5
$ just screenshot-all /styleguide-blog/
$ just check-page /styleguide-blog/ --theme bootstrap5
$ just compare-page /styleguide-blog/
If this is your first Playwright run on a machine, install browser binaries:
$ uv run playwright install chromium
Asset freshness checks¶
Detect stale built assets compared to source files:
$ just verify-assets
In DEBUG mode, django-cast also emits system check warning cast.W001
when local Vite source files are newer than the built manifest.
Podlove Performance Data¶
To create local podcast data that exercises the Podlove player:
$ cd example
$ uv run python scripts/create_podlove_perf_data.py --episodes 5 --transcripts 200
This creates a podcast at /show/ with multiple episodes and transcript
payloads to profile list and detail pages. Increase --transcripts to mimic
heavier payloads. If the slug already exists, delete the data or pick a
different --slug value.
Note
The Podlove subscribe button bundle is a vendored, minified asset (upstream last updated in 2019). If you apply a local patch for layout stability, add a short header comment with the upstream URL and patch date, and record the change in release notes.
Running Tests¶
Python Tests¶
Run the Python test suite:
$ just test
# or directly: uv run pytest
Run only the intentionally slower integration/dev-surface checks:
$ just test-slow
# or directly: uv run pytest -m slow
Run only the faster non-slow tests:
$ just test-fast
# or directly: uv run pytest -m "not slow"
For specific tests:
$ just test-one tests/models_test.py::TestPostModel::test_post_slug
Test Coverage¶
Generate a coverage report:
$ just coverage
This runs the tests with coverage and opens the HTML report in your browser.
Or manually:
$ uv run coverage run -m pytest
$ uv run coverage html
$ open htmlcov/index.html
Test Database Management¶
The test database is reused between test runs for performance. If you’ve added new migrations:
$ rm tests/test_database.sqlite3 # Remove old test database
$ uv run python manage.py migrate # Recreate with new migrations (uses tests.settings)
If you see widespread 404s or IntegrityErrors in tests (especially around Wagtail page URLs), the reused test database or Wagtail’s site-root path cache may be stale. In that case, recreate the test database using the steps above to reset the site root path cache and avoid leftover pages or slug collisions.
JavaScript Tests¶
Run JavaScript tests with Vitest:
$ just js-test
$ just js-test-watch
$ just js-coverage
# or directly:
$ cd javascript
$ npx vitest run
Build shipped JavaScript assets:
$ just js-build-comments
# or directly:
$ cd javascript
$ npm run build:comments
Testing Multiple Django/Wagtail Versions¶
Use tox to test against multiple Django and Wagtail versions:
$ just tox
# or directly: uv run tox
To test a specific environment:
$ uv run tox -e py312-django42-wagtail70
Code Quality¶
Run all quality checks (linting, type checking, and tests) in one command:
$ just check
This runs just lint, just typecheck, and just test in sequence,
stopping on first failure.
Linting and Formatting¶
Django-cast uses Ruff for code formatting and linting. The project is configured with:
Line length: 119 characters
Black-compatible formatting
Import sorting
Format your code:
$ just lint
Fix linting issues:
$ uv run ruff format .
$ uv run ruff check --fix .
Pre-commit Hooks¶
Set up pre-commit hooks to automatically check code quality:
$ pre-commit install
Run all hooks manually:
$ just pre-commit
# or directly: pre-commit run --all-files
The pre-commit configuration includes:
Ruff formatting and linting
djhtml template formatting
Trailing whitespace removal
End-of-file fixes
YAML validation
Type Checking¶
Run mypy for static type checking:
$ just typecheck
# or directly: uv run mypy
The project uses type hints throughout the codebase. When adding new code, please include appropriate type annotations.
Configuration for mypy is in pyproject.toml. Key settings include:
python_version = "3.14"ignore_missing_imports = trueplugins = ["mypy_django_plugin.main"]
Building Documentation¶
The documentation uses Sphinx with the Furo theme.
Building Locally¶
Build the documentation:
$ just docs
Or manually:
$ make -C docs clean
$ make -C docs html
View the built documentation:
$ open docs/_build/html/index.html
Documentation Standards¶
Use reStructuredText format for documentation files
Include code examples where appropriate
Document all public APIs
Keep documentation up-to-date with code changes
Writing Documentation¶
When adding new features:
Update relevant .rst files in the
docs/directoryAdd docstrings to new Python functions/classes
Include usage examples
Update the changelog if applicable
Package Building¶
Django-cast uses the uv_build backend (not hatchling). Configuration is in pyproject.toml:
Build backend:
uv_buildSource layout:
src/cast/Module configuration:
module-root = "src"andmodule-name = "cast"
To build the package locally:
$ uv build
This creates wheel and source distributions in the dist/ directory.
For the complete release process, see Release Process.
Development Workflow¶
Branch Strategy¶
main: Stable releases onlydevelop: Active developmentFeature branches: Branch from
developfor new featuresHotfix branches: Branch from
mainfor critical fixes
Making Changes¶
Create a feature branch from
developMake your changes
Add tests for new functionality
Run
just check(linting, type checking, and tests in one command)Update documentation
Create a pull request to
develop
Pull Request Guidelines¶
Include a clear description of changes
Reference any related issues
Ensure all tests pass
Maintain or improve code coverage
Update documentation as needed
Follow the existing code style
Debugging Tips¶
Django Extensions¶
The example project enables django-extensions in example/example_site/settings/dev.py (e.g. shell_plus).
Optional Debug Toolbar¶
If you want to use Django Debug Toolbar, add it to your environment and enable it in
example/example_site/settings/local.py (which is imported from dev.py if present).
Logging¶
Enable detailed logging during development:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'cast': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
Common Issues¶
Import Errors¶
Since the project uses src layout (src/cast/), ensure:
The project is installed into your environment (
just install/uv sync)Imports use
cast(notsrc.cast)PYTHONPATH includes src directory when needed
Database Migration Conflicts¶
When working with migrations:
Always create migrations on the latest
developbranchIf conflicts occur, delete and recreate migrations
Squash migrations periodically to keep them manageable
Getting Help¶
Open an issue on GitHub
Check existing issues and pull requests
Review the Contributing guide
Ask questions in discussions
Additional Resources¶
Contributing - Contribution guidelines