Skip to main content

Contribution Guide

We welcome contributions to Django-Chassis. This guide covers the local workflow for development, testing, and documentation.

If you are not sure whether a change fits the project, open an issue or a draft pull request first.

Please keep changes focused and include tests when behavior changes.

Setting up environment

The project uses uv for Python dependency management. To install it, follow the official guide in the uv documentation.

After cloning the repository, install dependencies:

uv sync --group dev

Linting

uv run ruff check .
uv run pyrefly check
uv run pytest tests/test_source_conventions.py -q

Ruff checks both the package and the test suite. Keep rule exceptions scoped to the narrowest matching file or path and document why the framework contract requires them. The configured Cyrillic confusables support Russian UI strings and docstrings without disabling the RUF001RUF003 checks.

B009 and B010 are disabled because Django integrations legitimately read and attach dynamic attributes on framework objects with getattr() and setattr(); forcing direct access would require artificial protocols solely for the type checker.

Pyrefly checks django_chassis with the strict preset and the minimum supported Python version. The stylistic missing-override-decorator and implicit-any-lambda rules are disabled. implicit-any-attribute is disabled to keep Django model Meta assignments unannotated; incompatible method signatures remain errors through bad-override.

Testing

uv run pytest

The GitHub Actions test pipeline runs linting and strict type checks on Python 3.13, then runs the complete test suite on Python 3.13 and 3.14. Matrix jobs do not stop after the first failure, so every supported Python version reports its result.

Working with documentation

Documentation is built with Docusaurus. The site is bilingual (English source, Russian mirrors) and is not versioned. Public API is marked with <Since v="x.y.z" /> badges instead.

cd docs
npm install
npm run docs:dev

English is the default locale at /. Russian is the i18n overlay at /ru/. docs:dev serves English on port 3000, Russian on 3001 (under /ru/), and proxies /ru from the English server so the locale dropdown works. Use docs:dev, not docs:dev:ru alone, if you need to switch languages.

npm run docs:build
npm run docs:serve

Version badges

Any new public option, component, page, setting, or extra must be marked in both languages:

<Since v="1.1.0" />

Behaviour or signature changes use <Changed v="..." /> and a CHANGELOG.md entry. The badge version is the package version that first shipped the feature, not a documentation version.

Project conventions

  • Full typing — annotate every function parameter, return value, and variable except attributes inside Django model Meta classes. The project targets pyrefly strict mode. Runtime Django classes that do not support parameterization, such as Field and ModelAdmin, remain unparameterized in annotations.
  • No relative imports — always use absolute imports (from django_chassis.mixins import ChassisAdminMixin).
  • Keyword arguments — pass arguments by keyword where possible.
  • Function signatures — if a signature does not fit on one line, put every parameter on its own line.
  • Trailing commas — do not leave an optional comma after the final parameter, argument, or collection item. Ruff formatter is disabled because it requires trailing commas in multiline collections. COM819 handles its supported cases, and the source-conventions checker covers multiline syntax.
  • Formatting — do not run ruff format; use uv run ruff check . for automated style checks.
  • Migrations — never edit or mechanically rewrite files in Django migrations directories. They are globally excluded from pre-commit, Ruff, Pyrefly, and source-conventions checks.
  • ImportsI001 is disabled because isort requires trailing commas in multiline import blocks. Absolute-import enforcement remains enabled.
  • Lambda expressions — preserve concise lambdas; do not replace them with named functions or direct references solely for linting or typing.
  • Noqa directives — preserve existing # noqa comments; do not remove or rewrite maintainer-added suppressions unless explicitly requested.
  • Model managers — declare Django model Manager and QuerySet classes in django_chassis.models.managers, not in model modules.
  • Django model metadata — use plain assignments inside model Meta classes; do not add type annotations, including to default_permissions = (). The source-conventions checker enforces this; Pyrefly's implicit-any-attribute rule is disabled so it cannot require an annotation for an empty tuple.
  • Class names — do not create classes whose names start with _ without explicit maintainer permission; use a descriptive public name instead.
  • uv run — run Python commands as uv run pytest, not bare python.
  • options stays options — do not rename the ModelAdmin attribute.
  • Mixin orderChassisAdminMixin / ChassisAdminSiteMixin before the Django class.
  • INSTALLED_APPS order'django_chassis' before 'django.contrib.admin'.
  • English and Russian docs stay in sync.
  • Public API changes need a CHANGELOG.md entry.