Boost Your Django DX updated again

I have just released the second update to Boost Your Django DX, my book of developer experience (DX) recommendations for Django projects. This update contains a new chapter, changes some recommended tools, and upgrades to Python 3.13 and Django 5.1. Overall, the book is 45 pages longer, now totalling 326!
The most significant new addition is a chapter on debuggers: Python’s built-in one, pdb, and IPython’s enhanced version, ipdb. The chapter introduces pdb with realistic examples, covers all the essential commands, and includes many tips, like using the .pdbrc configuration file.
Another major change is swapping the recommended CSS and JavaScript tools from ESLint and Prettier to Biome. Biome is a super-fast formatter and linter for CSS, JavaScript, JSON, TypeScript, and more. The new section introduces it and provides integration advice for Django projects.
Thank you to everyone who has supported the book so far. Just the other day, it reached fifty five-star reviews. I am very grateful for all the feedback from the community and aim to keep improving the book.
This update is free for all who previously purchased the book. To help readers catch up, the introduction chapter has a changelog with links to the updated sections, reproduced below.
Boost Your Django DX and all my other books are currently discounted 50% for Black Friday. This stacks with the automatic discount to match local purchasing power in your country and the DX bundle deal.
May your workflow be ever more efficient and your code bug free,
—Adam
Changelog
Restructured the book:
- The first and last chapters are now called “Introduction” and “Outroduction”, for consistency with my other books.
- The documentation chapter has moved from the start of the book to the middle, to make the start more exciting.
- The code quality tools chapters have been reorganized, spreading the content from two chapters to three, with a new chapter titled “Python code quality tools”.
Upgraded to Python 3.13 and Django 5.1.
Added a chapter on debuggers, covering ways to use pdb and ipdb within your Django project. Previously, the IPython section had a short mention of ipdb, with the sentence:
pdb is fantastic and worth learning, but that’s for another book or blog post…
Well, that’s not in another book or blog post, it’s here now. Enjoy and happy debugging.
Added a section on Djade, my new tool for formatting Django templates.
Added a section on Biome, a formatter and linter for CSS, JavaScript, JSON, TypeScript, and more. This tool replaces my recommendations for ESLint and Prettier, which have been removed per the below release notes.
Added a section on IPython’s
%whoand%whosmagic commands.Updated the isort section to cover the
force_single_lineoption.Updated the Flake8 section to demonstrate some rules and recommend disabling E501, the maximum line length rule. I don’t think it’s worth the effort to fix or individually ignore most “line too long” errors.
Added Django TV and django-classy-doc to Bonus Django documentation sites.
Edited the Black section to cover setting the target version with
project.requires-python, rather thantool.black.target-version.Removed the section on reorder-python-imports. Unfortunately, it is incompatible with Black version 24, with no fix planned. I recommend using isort instead, which is Black-compatible and can apply a similar style with the
force_single_lineoption.Removed the (rather small) section on Mypy. It didn’t really provide much value.
Removed the section on DjHTML. Whilst still a nice tool, its indentation modification can break some whitespace-sensitive contexts, such as
<pre>tags. Also it removes formatting indentation from inline JavaScript, often used with frameworks like Alpine.js.Removed the section on ESLint. It no longer operates correctly under pre-commit since its version 9 release, and I recommend using Biome instead.
Removed the section on Prettier. Its pre-commit hook is no longer maintained, and I recommend using Biome instead.
Table of contents
- Introduction
- About this book
- Read in any order
- Example commands and resources
- End-of-chapter feedback links
- Acknowledgements
- Changelog
- About this book
- Virtual environments and dependencies
- On tools and choice
- Virtual environments
- Create a virtual environment with venv
- Avoid committing your virtual environment
- Activate a virtual environment
- Deactivate a virtual environment
- Maybe use virtualenv instead of venv
- Pip and extra tools
- Invoke Pip safely
- The problems with
pip freeze > requirements.txt - pip-compile: simple dependency management
- Convert an existing
requirements.txtfile topip-compile - Add a new dependency with
pip-compile - Remove a dependency With
pip-compile - Upgrade dependencies with
pip-compile - pip-lock: keep all environments up to date
- Dependency management
- Stick to a single set of dependencies (probably)
- Pick new dependencies carefully
- Set a dependency upgrade schedule
- Python’s Development Mode
- Enable development mode
- Check if development mode is enabled
- When to use development mode
- Python shell
- The
shellcommand- Execute a string with
-c - Execute a temporary file with
-c 'import t'
- Execute a string with
- IPython: a superior Python shell
- Install IPython
- Get help with
?or?? - Advanced autocomplete with tab
- Reuse results with the output history
- Export and rerun code with the input history
- Copy in code with multi-line paste and
%cpaste - Iterate quickly with autoreload
- List all imported names with
%whoand%whos - Start IPython within your code with
IPython.embed() - Benchmark code with
%timeit
- django-read-only: production data protection
- Quickly toggle read-only mode in IPython with
%read_only
- Quickly toggle read-only mode in IPython with
- The
- Debuggers
- pdb: Python’s built-in debugger
- Some initial examples
- Basic commands
- Ways to start pdb
- Extend pdb with
.pdbrc - Write snapshot-style tests quickly with
--pdb
- ipdb: IPython enhancements to pdb
- Extra features
- Install and use ipdb
- pdb: Python’s built-in debugger
- Development server
- Django Debug Toolbar: a development boon
- Install and configure
- Explore the toolbar
- Find problematic database queries with the SQL panel
- Trace non-HTML requests with the history panel
- django-browser-reload: automatically reload your browser in development
- Reloads triggered by template changes
- Reloads triggered by static asset changes
- Reloads triggered by code changes
- Installation
- Rich: beautiful terminal output
- Server logs
- Management commands
- Django Debug Toolbar: a development boon
- Code quality tools
- EditorConfig: consistent text editing
- pre-commit: a code quality framework
- What pre-commit is
- Install pre-commit
- Add a configuration file
- Configuration structure
- Pin language versions with
default_language_version - Various ways to run hooks
- Update hooks With
pre-commit autoupdate - Run pre-commit in CI with pre-commit ci
- Introduce a hook incrementally
- Python code quality tools
- Black: the uncompromising code formatter
- How Black formats code
- Install and configure Black
- isort: sorted, grouped import statements
- isort’s style
- Split
fromimports one-per-line withforce_single_line - Install and configure isort
- Add or remove imports from every file
- Flake8: an extensible linter
- Linting examples
- Install and configure Flake8
- flake8-bugbear: extra checks for common problems
- flake8-no-pep420: avoid package problems
- Further plugins
- pyupgrade: upgrade to the latest Python syntax
- Some example rewrites
- Install and configure
- django-upgrade: upgrade to the latest Django features
- Example rewrites
- Install and configure
- Black: the uncompromising code formatter
- Further code quality tools
- Djade: a template formatter
- Formatting examples
- Install and configure
- Biome: a linter-formatter for CSS, JavaScript, JSON, and more
- CSS formatting examples
- CSS linting examples
- JavaScript formatting examples
- JavaScript linting examples
- JSON, TypeScript, and other languages
- Install and configure
- ShellCheck: find bugs in your shell scripts
- An example
- Install
- blacken-docs: apply Black to documentation
- pre-commit-hooks: general purpose checks
- Djade: a template formatter
- Build your own tools
- pre-commit’s virtual languages: rapid checks
- Block files based on name with a custom “fail” hook
- Block files based on content with a regular expression hook
- Flake8 plugin: custom source code checks
- The Abstract Syntax Tree (AST)
- Further AST exploration
- Plugin structure
- Make a plugin to ban
lambda - Test your plugin
- Further reading
- Write a custom tool
- Replace Django documentation links
- What pre-commit expects of tools
- Make a tool
- Example usage
- Run the tool with pre-commit
- Add tests
- pre-commit’s virtual languages: rapid checks
- Documentation
- DevDocs: the free rapid documentation tool
- Get started and set up Django’s docs
- Perform a basic search
- Search a single documentation source
- Reset the search box
- Visit the original documentation site
- Download documentation sources for offline use
- Useful documentation sources
- More on DevDocs
- DuckDuckGo: a developer-friendly search engine
- Access DuckDuckGo
- Keyboard shortcuts
- Bangs: shortcuts to other search pages
- Instant Answers: expanded results on the first page
- Bonus Django documentation sites
- Classy Class-Based Views
- Classy Django Forms
- Template Tags and Filters
- Classy Django REST Framework
- Awesome Django
- Django TV
- A bonus bonus: django-classy-doc
- Wget: download any website
- Install
- How to download a website
- Example: the Django REST Framework documentation
- Read offline documentation with Python’s web server
- An explanation of all the flags
- Miscellaneous tips and tricks
- Python documentation
- Django documentation
- Read the Docs
- Sphinx
- DevDocs: the free rapid documentation tool
- Settings
- Structure your settings
- Use a single settings file with environment variables
- Load a
.envfile locally - Settings in tests
- Group and sort settings
- Order
INSTALLED_APPS - Use
pathlibforBASE_DIR - A settings file template
- Some settings patterns to avoid
- Don’t read settings at import time
- Avoid direct setting changes
- Don’t import your project settings module
- Avoid creating custom settings where module constants would do
- Avoid creating dynamic module constants instead of settings
- Name your custom settings well
- Override complex settings correctly
- Test your settings file
- Test your settings functions
- Test your settings logic
- Structure your settings
- Models and migrations
- Seed your database with a custom management command
- Sample data approaches
- Create a command
- Test your command
- Factory Boy: easier data generation
- Install and define factories
- Invoke factories
- Use factories in tests
- Use factories in
seed_database - Further features
- Migration safeguards
- Test for pending migrations
- django-linear-migrations: prevent merge migrations
- Seed your database with a custom management command
- System checks
- How system checks work
- The basics
- How to silence checks
- The advantages of checks
- Write your own checks
- How to write a check function
- How to register a check function
- Add a check for Python’s development mode
- Add a check for model class names
- Test your checks
- Test the development mode check
- Test the model name check
- Further places that checks live
- Model class checks
- Model field checks
- django-version-checks: keep your environments in sync
- Install and configure
- Upgrading dependencies
- How system checks work
- Outroduction
- Further reading
- Thank you
One summary email a week, no spam, I pinky promise.
Tags: django