django-admin-inline-controls 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_admin_inline_controls-0.1.0/.github/workflows/compat-matrix.yml +27 -0
- django_admin_inline_controls-0.1.0/.github/workflows/js-tests.yml +24 -0
- django_admin_inline_controls-0.1.0/.github/workflows/pre-commit.yml +26 -0
- django_admin_inline_controls-0.1.0/.github/workflows/pytest.yml +31 -0
- django_admin_inline_controls-0.1.0/.github/workflows/release.yml +55 -0
- django_admin_inline_controls-0.1.0/.gitignore +42 -0
- django_admin_inline_controls-0.1.0/.pre-commit-config.yaml +68 -0
- django_admin_inline_controls-0.1.0/CHANGELOG.md +52 -0
- django_admin_inline_controls-0.1.0/CONTRIBUTING.md +113 -0
- django_admin_inline_controls-0.1.0/LICENSE +21 -0
- django_admin_inline_controls-0.1.0/PKG-INFO +823 -0
- django_admin_inline_controls-0.1.0/README.md +770 -0
- django_admin_inline_controls-0.1.0/biome.json +19 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/.gitkeep +0 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/actions.png +0 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/footer-rows.png +0 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/hero.png +0 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/row-actions.png +0 -0
- django_admin_inline_controls-0.1.0/docs/screenshots/save-inline.png +0 -0
- django_admin_inline_controls-0.1.0/docs/themes/unfold/stacked.png +0 -0
- django_admin_inline_controls-0.1.0/docs/themes/unfold/tab-dark.png +0 -0
- django_admin_inline_controls-0.1.0/docs/themes/unfold/tabular.png +0 -0
- django_admin_inline_controls-0.1.0/docs/themes/unfold.md +63 -0
- django_admin_inline_controls-0.1.0/example/demo/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/example/demo/admin.py +104 -0
- django_admin_inline_controls-0.1.0/example/demo/admin_unfold.py +39 -0
- django_admin_inline_controls-0.1.0/example/demo/management/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/example/demo/management/commands/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/example/demo/management/commands/seed_demo.py +46 -0
- django_admin_inline_controls-0.1.0/example/demo/migrations/0001_initial.py +43 -0
- django_admin_inline_controls-0.1.0/example/demo/migrations/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/example/demo/models.py +38 -0
- django_admin_inline_controls-0.1.0/example/example/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/example/example/settings.py +66 -0
- django_admin_inline_controls-0.1.0/example/example/settings_unfold.py +8 -0
- django_admin_inline_controls-0.1.0/example/example/urls.py +6 -0
- django_admin_inline_controls-0.1.0/example/example/urls_unfold.py +6 -0
- django_admin_inline_controls-0.1.0/example/example/wsgi.py +7 -0
- django_admin_inline_controls-0.1.0/example/manage.py +20 -0
- django_admin_inline_controls-0.1.0/package-lock.json +2963 -0
- django_admin_inline_controls-0.1.0/package.json +16 -0
- django_admin_inline_controls-0.1.0/pyproject.toml +145 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/__init__.py +1 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/actions.py +176 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/apps.py +7 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/checks.py +212 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/contrib/__init__.py +4 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/contrib/filters.py +69 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/contrib/nested.py +77 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/contrib/unfold.py +85 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/controls.py +684 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/locale/es/LC_MESSAGES/django.mo +0 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/locale/es/LC_MESSAGES/django.po +232 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/mixins.py +932 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/py.typed +0 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/row_actions.py +173 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/css/contrib/unfold.css +111 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/css/core.css +294 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/js/actions.js +330 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/js/contrib/unfold.js +21 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/js/core.js +570 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/static/django_admin_inline_controls/js/save.js +109 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/footer.html +99 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/inline.html +34 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/inline_response.html +14 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/row_actions.html +19 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/tfoot.html +36 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templates/django_admin_inline_controls/toolbar.html +93 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templatetags/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/templatetags/inline_controls.py +72 -0
- django_admin_inline_controls-0.1.0/src/django_admin_inline_controls/types.py +40 -0
- django_admin_inline_controls-0.1.0/tests/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/tests/admin.py +108 -0
- django_admin_inline_controls-0.1.0/tests/conftest.py +54 -0
- django_admin_inline_controls-0.1.0/tests/e2e/__init__.py +0 -0
- django_admin_inline_controls-0.1.0/tests/e2e/test_e2e.py +507 -0
- django_admin_inline_controls-0.1.0/tests/js/inline_controls.test.js +755 -0
- django_admin_inline_controls-0.1.0/tests/settings.py +61 -0
- django_admin_inline_controls-0.1.0/tests/templates/custom/footer.html +5 -0
- django_admin_inline_controls-0.1.0/tests/templates/custom/inline.html +5 -0
- django_admin_inline_controls-0.1.0/tests/templates/custom/tfoot.html +3 -0
- django_admin_inline_controls-0.1.0/tests/templates/custom/themed_tabular.html +33 -0
- django_admin_inline_controls-0.1.0/tests/templates/custom/toolbar.html +7 -0
- django_admin_inline_controls-0.1.0/tests/test_actions.py +363 -0
- django_admin_inline_controls-0.1.0/tests/test_checks.py +45 -0
- django_admin_inline_controls-0.1.0/tests/test_contrib.py +194 -0
- django_admin_inline_controls-0.1.0/tests/test_edge_cases.py +140 -0
- django_admin_inline_controls-0.1.0/tests/test_footer_rows.py +479 -0
- django_admin_inline_controls-0.1.0/tests/test_helpers.py +132 -0
- django_admin_inline_controls-0.1.0/tests/test_i18n.py +144 -0
- django_admin_inline_controls-0.1.0/tests/test_inline_controls.py +312 -0
- django_admin_inline_controls-0.1.0/tests/test_media.py +73 -0
- django_admin_inline_controls-0.1.0/tests/test_row_actions.py +400 -0
- django_admin_inline_controls-0.1.0/tests/test_save_inline.py +217 -0
- django_admin_inline_controls-0.1.0/tests/test_selectors.py +78 -0
- django_admin_inline_controls-0.1.0/tests/test_templates.py +111 -0
- django_admin_inline_controls-0.1.0/tests/urls.py +12 -0
- django_admin_inline_controls-0.1.0/uv.lock +1546 -0
- django_admin_inline_controls-0.1.0/vitest.config.js +15 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Compatibility Matrix
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
tox:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v5
|
|
17
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
|
|
20
|
+
- name: Install Python versions
|
|
21
|
+
run: uv python install 3.10 3.12 3.13 3.14
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync
|
|
25
|
+
|
|
26
|
+
- name: Run compatibility matrix (tox)
|
|
27
|
+
run: uv run tox run
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: JavaScript Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Setup Node.js
|
|
15
|
+
uses: actions/setup-node@v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: "20"
|
|
18
|
+
cache: "npm"
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Run Tests & Coverage
|
|
24
|
+
run: npm run coverage
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Pre-commit
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
pre-commit:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Install uv
|
|
15
|
+
uses: astral-sh/setup-uv@v5
|
|
16
|
+
with:
|
|
17
|
+
enable-cache: true
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
run: uv python install
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: uv sync
|
|
24
|
+
|
|
25
|
+
- name: Run pre-commit
|
|
26
|
+
run: uv run pre-commit run --all-files
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Python and Playwright Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test-python:
|
|
11
|
+
name: Python Tests
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
enable-cache: true
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
run: uv python install
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: uv sync
|
|
26
|
+
|
|
27
|
+
- name: Install Playwright browsers
|
|
28
|
+
run: uv run playwright install --with-deps chromium
|
|
29
|
+
|
|
30
|
+
- name: Run Pytest
|
|
31
|
+
run: uv run pytest
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types:
|
|
6
|
+
- published
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release-build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v5
|
|
17
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
|
|
20
|
+
- name: Show project version
|
|
21
|
+
run: |
|
|
22
|
+
grep "version" pyproject.toml
|
|
23
|
+
|
|
24
|
+
- name: Build release distributions
|
|
25
|
+
run: uv build
|
|
26
|
+
|
|
27
|
+
- name: Upload distributions
|
|
28
|
+
uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: release-dists
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
pypi-publish:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
needs:
|
|
36
|
+
- release-build
|
|
37
|
+
permissions:
|
|
38
|
+
id-token: write
|
|
39
|
+
contents: read
|
|
40
|
+
|
|
41
|
+
environment:
|
|
42
|
+
name: pypi
|
|
43
|
+
url: https://pypi.org/project/django-admin-inline-controls/
|
|
44
|
+
|
|
45
|
+
steps:
|
|
46
|
+
- name: Retrieve release distributions
|
|
47
|
+
uses: actions/download-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: release-dists
|
|
50
|
+
path: dist/
|
|
51
|
+
|
|
52
|
+
- name: Publish release distributions to PyPI
|
|
53
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
54
|
+
with:
|
|
55
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.installed.cfg
|
|
9
|
+
*.egg
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
env/
|
|
15
|
+
|
|
16
|
+
# Testing / coverage
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
.coverage.*
|
|
20
|
+
coverage/
|
|
21
|
+
htmlcov/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
.tox/
|
|
25
|
+
|
|
26
|
+
# Django
|
|
27
|
+
*.log
|
|
28
|
+
local_settings.py
|
|
29
|
+
db.sqlite3
|
|
30
|
+
db.sqlite3-journal
|
|
31
|
+
media/
|
|
32
|
+
|
|
33
|
+
# Node / JS
|
|
34
|
+
node_modules/
|
|
35
|
+
|
|
36
|
+
# Editors / OS
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
.DS_Store
|
|
40
|
+
|
|
41
|
+
# Docs
|
|
42
|
+
docs/_build/
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
default_language_version:
|
|
2
|
+
python: &python-version python3.14
|
|
3
|
+
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
6
|
+
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
|
|
7
|
+
hooks:
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
- id: check-case-conflict
|
|
10
|
+
- id: check-json
|
|
11
|
+
- id: check-merge-conflict
|
|
12
|
+
- id: check-symlinks
|
|
13
|
+
- id: check-toml
|
|
14
|
+
- id: debug-statements
|
|
15
|
+
- id: end-of-file-fixer
|
|
16
|
+
- id: trailing-whitespace
|
|
17
|
+
|
|
18
|
+
- repo: https://github.com/biomejs/pre-commit
|
|
19
|
+
rev: d1ce4972fb5ad09afd33b432bca71e8c5dfbb2b5 # frozen: v2.5.6
|
|
20
|
+
hooks:
|
|
21
|
+
- id: biome-check
|
|
22
|
+
additional_dependencies:
|
|
23
|
+
- '@biomejs/biome@2.3.8'
|
|
24
|
+
language_version: default
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/adamchainz/django-upgrade
|
|
27
|
+
rev: bdcc9646c249f00ec9781751791e7b75b48b3722 # frozen: 1.31.1
|
|
28
|
+
hooks:
|
|
29
|
+
- id: django-upgrade
|
|
30
|
+
args: [--target-version, "4.2"]
|
|
31
|
+
|
|
32
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
33
|
+
rev: 39d9ac5938dadb73df0564a45f163e25ff9fa6e2 # frozen: v0.16.1
|
|
34
|
+
hooks:
|
|
35
|
+
- id: ruff-check
|
|
36
|
+
args: [--fix]
|
|
37
|
+
- id: ruff-format
|
|
38
|
+
|
|
39
|
+
- repo: local
|
|
40
|
+
hooks:
|
|
41
|
+
- id: mypy
|
|
42
|
+
name: mypy
|
|
43
|
+
entry: mypy
|
|
44
|
+
language: python
|
|
45
|
+
additional_dependencies:
|
|
46
|
+
- mypy>=1.10
|
|
47
|
+
- django-stubs[compatible-mypy]>=5
|
|
48
|
+
- django>=4.2
|
|
49
|
+
- django-filter>=23.2
|
|
50
|
+
- django-nested-admin>=4.1
|
|
51
|
+
- pytest-django>=4.8
|
|
52
|
+
types: [python]
|
|
53
|
+
files: ^(src|example)/
|
|
54
|
+
pass_filenames: false
|
|
55
|
+
args: [src/django_admin_inline_controls, example]
|
|
56
|
+
|
|
57
|
+
# Only needed if the library ships Django templates (src/<pkg>/templates/).
|
|
58
|
+
# Remove this hook if it doesn't.
|
|
59
|
+
- repo: https://github.com/adamchainz/djade-pre-commit
|
|
60
|
+
rev: 52a7ce253113456c2a1113186a4a19b15c8b68af # frozen: 1.9.0
|
|
61
|
+
hooks:
|
|
62
|
+
- id: djade
|
|
63
|
+
files: '(/|^)templates/'
|
|
64
|
+
|
|
65
|
+
- repo: https://github.com/tox-dev/pyproject-fmt
|
|
66
|
+
rev: d600c142bb19f521ae6a6a345f94a2efd7937759 # frozen: v2.26.0
|
|
67
|
+
hooks:
|
|
68
|
+
- id: pyproject-fmt
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-10-05
|
|
9
|
+
|
|
10
|
+
First release.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`InlineControlsMixin`** for `TabularInline` and `StackedInline`:
|
|
15
|
+
- pagination, with page links or infinite scroll, and saving rows loaded
|
|
16
|
+
across several pages;
|
|
17
|
+
- filters, generated from lookups or from a form of yours
|
|
18
|
+
(`contrib.filters` for a django-filter `FilterSet`);
|
|
19
|
+
- multi-column sorting from the column headers;
|
|
20
|
+
- state namespaced per inline in the URL, and in-place refresh of a
|
|
21
|
+
single inline (re-initializing the admin's inline and widget JS) with
|
|
22
|
+
an unsaved-changes prompt.
|
|
23
|
+
- **Saving one inline** (`inline_save_button`, with
|
|
24
|
+
`InlineControlsAdminMixin` on the parent): without submitting or
|
|
25
|
+
reloading the rest of the page, recorded in the parent's history.
|
|
26
|
+
- **Bulk actions** (`inline_bulk_actions`): like the changelist's, on the
|
|
27
|
+
selected rows, with "select all" across pages, the `@inline_action`
|
|
28
|
+
decorator (permissions, confirmation prompts) and a built-in
|
|
29
|
+
`delete_selected`.
|
|
30
|
+
- **Row actions** (`inline_actions`): buttons on each saved row, with
|
|
31
|
+
django-inline-actions' API — the `(request, obj, parent_obj)` signature,
|
|
32
|
+
`get_inline_actions()`, per-row `get_<action>_label/css/attr()` hooks and
|
|
33
|
+
the `ViewAction`, `DeleteAction` and `DefaultActionsMixin` mixins — run
|
|
34
|
+
without submitting the change form, with the permissions checked by the
|
|
35
|
+
server.
|
|
36
|
+
- **Footer rows** (`inline_footer_rows`, `inline_footer_scope`): totals,
|
|
37
|
+
averages… aggregated in one query over the filtered rows or the page,
|
|
38
|
+
rendered by the server as the table's `<tfoot>` (also in the add view,
|
|
39
|
+
empty) or as a summary line; raw values in `data-*` attributes for the
|
|
40
|
+
page's JS; format (`format_inline_footer_value()`) and markup
|
|
41
|
+
(`tfoot.html`) customizable.
|
|
42
|
+
- **Customizable markup:** template blocks throughout, per-inline
|
|
43
|
+
templates, and `inline_controls_selectors` (`DEFAULT_SELECTORS`) for
|
|
44
|
+
themes and custom inline templates, plus the `inline-controls:place` and
|
|
45
|
+
`inline-controls:updated` events.
|
|
46
|
+
- **django-unfold** support (`contrib.unfold`, `unfold` extra): the
|
|
47
|
+
controls in Unfold's inlines with its colors, light and dark.
|
|
48
|
+
- **django-nested-admin** support (`contrib.nested`, `nested` extra).
|
|
49
|
+
- Only the scripts an inline uses are loaded (`core.js`, `save.js`,
|
|
50
|
+
`actions.js`).
|
|
51
|
+
- Spanish translation, and system checks for every option.
|
|
52
|
+
- Django 4.2 – 6.1, Python 3.10+.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Development setup
|
|
4
|
+
|
|
5
|
+
With [uv](https://docs.astral.sh/uv/) (recommended):
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
uv run playwright install --with-deps chromium
|
|
10
|
+
npm install
|
|
11
|
+
uv run pre-commit install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Without uv:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install -e ".[dev]"
|
|
18
|
+
playwright install --with-deps chromium
|
|
19
|
+
npm install
|
|
20
|
+
pre-commit install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Running the example project
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd example
|
|
27
|
+
python manage.py migrate
|
|
28
|
+
python manage.py createsuperuser
|
|
29
|
+
python manage.py runserver
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tests
|
|
33
|
+
|
|
34
|
+
Python (pytest + pytest-django, coverage always on via `addopts`):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv run pytest
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`tests/e2e/` (real-browser tests via pytest-playwright, driving a real
|
|
41
|
+
Chromium against `live_server`) runs as part of that same `uv run pytest`
|
|
42
|
+
— no separate command. They need `uv run playwright install chromium`
|
|
43
|
+
once (see Setup above) and are slower than the rest of the suite;
|
|
44
|
+
everything else under `tests/` is unit/integration-level and doesn't
|
|
45
|
+
touch a browser.
|
|
46
|
+
|
|
47
|
+
JavaScript (vitest + jsdom):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm test
|
|
51
|
+
npm run coverage
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Compatibility matrix (tox)
|
|
55
|
+
|
|
56
|
+
`uv run pytest` above only runs against whatever Django version `uv.lock`
|
|
57
|
+
resolved (the newest one satisfying `dependencies`). To check the full
|
|
58
|
+
supported range — every Django series in `classifiers`, against the
|
|
59
|
+
oldest and newest Python it supports (within this package's own
|
|
60
|
+
`requires-python` floor) — run the tox matrix instead:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
uv run tox run-parallel # every env, in parallel
|
|
64
|
+
uv run tox -e py314-dj52 # a single env, e.g. to debug one failure
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`[tool.tox]` in `pyproject.toml` lists the exact envs. Each one gets its own ephemeral venv (via
|
|
68
|
+
[tox-uv](https://github.com/tox-dev/tox-uv), using uv's own Python
|
|
69
|
+
builds — `uv python install <version>` once for any you don't have yet)
|
|
70
|
+
with only `pytest`/`pytest-django`/`pytest-cov` and that env's pinned
|
|
71
|
+
Django, not the full `dev` group, and skips `tests/e2e/` (no Playwright
|
|
72
|
+
in those envs). This only tests boundaries (oldest + newest Python per
|
|
73
|
+
Django series), not every valid combination — that catches most real
|
|
74
|
+
breakage while staying fast. Runs in CI as a separate
|
|
75
|
+
`compat-matrix.yml` workflow, alongside the regular `pytest.yml`. Update
|
|
76
|
+
the `env_list` here whenever `classifiers` gains or drops a Django
|
|
77
|
+
series.
|
|
78
|
+
|
|
79
|
+
## Lint / format / type-check
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv run ruff check .
|
|
83
|
+
uv run ruff format --check .
|
|
84
|
+
uv run mypy src example
|
|
85
|
+
# or, everything at once:
|
|
86
|
+
uv run pre-commit run --all-files
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The mypy pre-commit hook runs against the project venv (it needs
|
|
90
|
+
django-stubs to resolve model types), not an isolated pre-commit env.
|
|
91
|
+
|
|
92
|
+
## Before opening a PR
|
|
93
|
+
|
|
94
|
+
- [ ] `uv run pytest`
|
|
95
|
+
- [ ] `npm test`
|
|
96
|
+
- [ ] `uv run pre-commit run --all-files`
|
|
97
|
+
|
|
98
|
+
## Translations
|
|
99
|
+
|
|
100
|
+
Catalogs live in `src/django_admin_inline_controls/locale/`. After changing
|
|
101
|
+
translatable text, from that package directory:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd src/django_admin_inline_controls
|
|
105
|
+
DJANGO_SETTINGS_MODULE=tests.settings PYTHONPATH=../..:../../example \
|
|
106
|
+
uv run django-admin makemessages -l es --no-obsolete --add-location file
|
|
107
|
+
# translate the new/changed entries in locale/es/LC_MESSAGES/django.po, then:
|
|
108
|
+
DJANGO_SETTINGS_MODULE=tests.settings PYTHONPATH=../..:../../example \
|
|
109
|
+
uv run django-admin compilemessages
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Commit both the `.po` and the compiled `.mo`. `tests/test_i18n.py` fails if
|
|
113
|
+
an entry is untranslated or fuzzy, or if a `.mo` is older than its `.po`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rodolfo Becerra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|