django-admin-react 0.2.0a8__tar.gz → 1.0.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_react-0.2.0a8 → django_admin_react-1.0.0}/PKG-INFO +70 -40
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/README.md +66 -38
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/audit.py +16 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/conf.py +26 -13
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/pwa.py +5 -1
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/static/admin_react/.vite/manifest.json +2 -2
- django_admin_react-1.0.0/django_admin_react/static/admin_react/assets/index-CcvXnwTT.js +8 -0
- django_admin_react-1.0.0/django_admin_react/static/admin_react/assets/index-Rr7dwEhe.css +1 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/static/admin_react/index.html +2 -2
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/templates/admin_react/index.html +7 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/urls.py +33 -11
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/views.py +41 -3
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/pyproject.toml +14 -2
- django_admin_react-0.2.0a8/django_admin_react/api/README.md +0 -31
- django_admin_react-0.2.0a8/django_admin_react/api/__init__.py +0 -5
- django_admin_react-0.2.0a8/django_admin_react/api/dates.py +0 -215
- django_admin_react-0.2.0a8/django_admin_react/api/filters.py +0 -412
- django_admin_react-0.2.0a8/django_admin_react/api/inlines.py +0 -358
- django_admin_react-0.2.0a8/django_admin_react/api/inlines_write.py +0 -241
- django_admin_react-0.2.0a8/django_admin_react/api/panels.py +0 -113
- django_admin_react-0.2.0a8/django_admin_react/api/permissions.py +0 -132
- django_admin_react-0.2.0a8/django_admin_react/api/registry.py +0 -399
- django_admin_react-0.2.0a8/django_admin_react/api/serializers.py +0 -467
- django_admin_react-0.2.0a8/django_admin_react/api/urls.py +0 -164
- django_admin_react-0.2.0a8/django_admin_react/api/views/README.md +0 -22
- django_admin_react-0.2.0a8/django_admin_react/api/views/__init__.py +0 -6
- django_admin_react-0.2.0a8/django_admin_react/api/views/actions.py +0 -196
- django_admin_react-0.2.0a8/django_admin_react/api/views/auth.py +0 -192
- django_admin_react-0.2.0a8/django_admin_react/api/views/autocomplete.py +0 -163
- django_admin_react-0.2.0a8/django_admin_react/api/views/bulk.py +0 -248
- django_admin_react-0.2.0a8/django_admin_react/api/views/create.py +0 -213
- django_admin_react-0.2.0a8/django_admin_react/api/views/create_form.py +0 -229
- django_admin_react-0.2.0a8/django_admin_react/api/views/delete_preview.py +0 -107
- django_admin_react-0.2.0a8/django_admin_react/api/views/destroy.py +0 -93
- django_admin_react-0.2.0a8/django_admin_react/api/views/detail.py +0 -482
- django_admin_react-0.2.0a8/django_admin_react/api/views/history.py +0 -166
- django_admin_react-0.2.0a8/django_admin_react/api/views/list.py +0 -493
- django_admin_react-0.2.0a8/django_admin_react/api/views/password.py +0 -161
- django_admin_react-0.2.0a8/django_admin_react/api/views/registry.py +0 -53
- django_admin_react-0.2.0a8/django_admin_react/api/views/schema.py +0 -494
- django_admin_react-0.2.0a8/django_admin_react/api/views/update.py +0 -220
- django_admin_react-0.2.0a8/django_admin_react/api/writes.py +0 -457
- django_admin_react-0.2.0a8/django_admin_react/static/admin_react/assets/index-BSzI7RU6.css +0 -1
- django_admin_react-0.2.0a8/django_admin_react/static/admin_react/assets/index-CxlHfz-w.js +0 -8
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/LICENSE +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/README.md +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/__init__.py +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/apps.py +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/templates/README.md +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/templates/admin_react/README.md +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/templates/admin_react/login.html +0 -0
- {django_admin_react-0.2.0a8 → django_admin_react-1.0.0}/django_admin_react/templates/admin_react/sw.js +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: django-admin-react
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A drop-in React single-page admin for Django, driven entirely by ModelAdmin.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: django,admin,react,spa,tailwind
|
|
7
7
|
Author: django-admin-react contributors
|
|
8
8
|
Requires-Python: >=3.10,<4.0
|
|
9
|
-
Classifier: Development Status ::
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
10
|
Classifier: Environment :: Web Environment
|
|
11
11
|
Classifier: Framework :: Django
|
|
12
12
|
Classifier: Framework :: Django :: 5.0
|
|
@@ -24,6 +24,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
24
24
|
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
25
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
26
|
Requires-Dist: django (>=5.0,<7.0)
|
|
27
|
+
Requires-Dist: django-admin-mcp-api (>=0.1.0a0,<0.2.0)
|
|
28
|
+
Requires-Dist: django-admin-rest-api (>=1.0.1,<2.0.0)
|
|
27
29
|
Project-URL: Documentation, https://github.com/MartinCastroAlvarez/django-admin-react#readme
|
|
28
30
|
Project-URL: Homepage, https://github.com/MartinCastroAlvarez/django-admin-react
|
|
29
31
|
Project-URL: Repository, https://github.com/MartinCastroAlvarez/django-admin-react
|
|
@@ -35,11 +37,42 @@ A drop-in **React single-page admin** for any Django 5+ project. Same
|
|
|
35
37
|
`pip install`, same `INSTALLED_APPS`, same `urls.py include()` — and
|
|
36
38
|
your `ModelAdmin` classes drive everything. No React code on your side.
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
```python
|
|
41
|
+
# settings.py
|
|
42
|
+
INSTALLED_APPS = [
|
|
43
|
+
# ...
|
|
44
|
+
"django.contrib.admin",
|
|
45
|
+
"django_admin_rest_api", # the JSON REST API (sibling package — pulled in as a dependency)
|
|
46
|
+
"django_admin_react", # this package — the React SPA on top of it
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
# urls.py
|
|
50
|
+
urlpatterns = [
|
|
51
|
+
path("admin/", admin.site.urls),
|
|
52
|
+
path("admin-react/", include("django_admin_react.urls")), # SPA + its API include
|
|
53
|
+
]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> **Beta — v1.0.0.** Available on PyPI; the SPA + the API
|
|
57
|
+
> ([`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/))
|
|
58
|
+
> + the MCP adapter
|
|
59
|
+
> ([`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/))
|
|
60
|
+
> all share the v1 wire contract. Track progress on the
|
|
40
61
|
> [Project board](https://github.com/users/MartinCastroAlvarez/projects/3)
|
|
41
62
|
> and the [Issues list](https://github.com/MartinCastroAlvarez/django-admin-react/issues).
|
|
42
63
|
|
|
64
|
+
## Three repos, one product
|
|
65
|
+
|
|
66
|
+
The project is split into three independently-published, cross-referenced repos so each piece can be consumed on its own merits:
|
|
67
|
+
|
|
68
|
+
| Repo | PyPI | Role |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| **[`django-admin-rest-api`](https://github.com/MartinCastroAlvarez/django-admin-api)** | [`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/) | The JSON REST API for the Django admin — same permissions, same `ModelAdmin`, no new features. The wire surface. |
|
|
71
|
+
| **`django-admin-react`** *(this repo)* | [`django-admin-react`](https://pypi.org/project/django-admin-react/) | The React SPA frontend. A **super-layer** that depends on `django-admin-rest-api` for every wire call. |
|
|
72
|
+
| **[`django-admin-mcp-api`](https://github.com/MartinCastroAlvarez/django-admin-mcp)** | [`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/) | Wire-protocol-only **MCP** adapter (call, manifest, …) over `django-admin-rest-api` — lets agents reach the same `ModelAdmin`-driven REST surface, no new functionality / permissions / validation. |
|
|
73
|
+
|
|
74
|
+
The wire contract itself lives in the **API repo** (`docs/api-contract.md` there). This README is about the SPA. The migration from "self-contained" to the 3-repo split is tracked in [META #544](https://github.com/MartinCastroAlvarez/django-admin-react/issues/544).
|
|
75
|
+
|
|
43
76
|
---
|
|
44
77
|
|
|
45
78
|
## Why django-admin-react
|
|
@@ -77,8 +110,8 @@ permissions at runtime from `GET /api/v1/registry/`. Add a new
|
|
|
77
110
|
|
|
78
111
|
Real captures of the **django-admin-react SPA** rendering the bundled
|
|
79
112
|
`examples/` apps — driven entirely by each app's `ModelAdmin`.
|
|
80
|
-
|
|
81
|
-
|
|
113
|
+
Captured **manually** against a local dev server (no Playwright / Cypress /
|
|
114
|
+
e2e tooling required).
|
|
82
115
|
|
|
83
116
|
| Sign in (package login) | Registry / home |
|
|
84
117
|
| -------------------------------------------------- | ----------------------------------------------------- |
|
|
@@ -103,34 +136,16 @@ emails, account numbers, or PII).
|
|
|
103
136
|
pip install django-admin-react
|
|
104
137
|
```
|
|
105
138
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
INSTALLED_APPS
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
"django.contrib.messages",
|
|
114
|
-
"django.contrib.staticfiles",
|
|
115
|
-
"django_admin_react", # ← add this
|
|
116
|
-
# ... your own apps
|
|
117
|
-
]
|
|
118
|
-
```
|
|
139
|
+
This pulls in the JSON API ([`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/))
|
|
140
|
+
and the MCP adapter ([`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/))
|
|
141
|
+
as transitive dependencies. The **two-line `INSTALLED_APPS` + one-line
|
|
142
|
+
URL include** at the top of this README is the *entire* integration.
|
|
143
|
+
Mount at any prefix you like — `/admin-react/`, `/staff/`,
|
|
144
|
+
`/back-office/` — just don't collide with `django.contrib.admin`'s
|
|
145
|
+
own mount.
|
|
119
146
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
from django.urls import include, path
|
|
123
|
-
|
|
124
|
-
urlpatterns = [
|
|
125
|
-
path("admin/", include("django_admin_react.urls")),
|
|
126
|
-
# any prefix is fine:
|
|
127
|
-
# path("admin-react/", include("django_admin_react.urls")),
|
|
128
|
-
# path("staff/", include("django_admin_react.urls")),
|
|
129
|
-
]
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
That is the entire integration. Log in as a staff user → modern,
|
|
133
|
-
Tailwind-styled SPA driven by your existing `ModelAdmin` classes.
|
|
147
|
+
Log in as a staff user → modern, Tailwind-styled SPA driven by your
|
|
148
|
+
existing `ModelAdmin` classes.
|
|
134
149
|
|
|
135
150
|
The wheel ships the **pre-built React bundle**. You do **not** need
|
|
136
151
|
Node, pnpm, or any frontend toolchain to install or run.
|
|
@@ -159,6 +174,16 @@ DJANGO_ADMIN_REACT = {
|
|
|
159
174
|
# active states. Hex only (validated);
|
|
160
175
|
# injected as the --dar-primary CSS var, so
|
|
161
176
|
# rebranding needs no React rebuild.
|
|
177
|
+
|
|
178
|
+
# Auth + API mount
|
|
179
|
+
"REACT_LOGIN": True, # bool — React-rendered login is the default;
|
|
180
|
+
# the SPA shell is served to anonymous users
|
|
181
|
+
# and posts to /api/v1/login/. Set False to
|
|
182
|
+
# opt back into the legacy admin HTML login.
|
|
183
|
+
"API_URL_PREFIX": None, # str | None — point the SPA at a separately-
|
|
184
|
+
# mounted django-admin-rest-api (e.g.
|
|
185
|
+
# "/api/api/v1/"). Default None keeps the
|
|
186
|
+
# inline include the package ships today.
|
|
162
187
|
}
|
|
163
188
|
```
|
|
164
189
|
|
|
@@ -462,8 +487,9 @@ register_field_type(MoneyField, vocab_type="decimal")
|
|
|
462
487
|
# code required.
|
|
463
488
|
```
|
|
464
489
|
|
|
465
|
-
|
|
466
|
-
|
|
490
|
+
Coining a brand-new `vocab_type` (with a matching SPA widget) is an
|
|
491
|
+
**API-repo** concern — open the issue at
|
|
492
|
+
[`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api).
|
|
467
493
|
|
|
468
494
|
### Pre-built `get_*` overrides still work
|
|
469
495
|
|
|
@@ -510,7 +536,6 @@ and the [project board](https://github.com/users/MartinCastroAlvarez/projects/3)
|
|
|
510
536
|
✅ = shipped in the current alpha. 🟡 = not yet built (tracked). This
|
|
511
537
|
column is the **backend** capability only — for which surfaces the React
|
|
512
538
|
UI renders today, see the [frontend tracker (#160)](https://github.com/MartinCastroAlvarez/django-admin-react/issues/160).
|
|
513
|
-
[`ACCEPTANCE.md`](ACCEPTANCE.md) carries the full criterion-by-criterion list.
|
|
514
539
|
|
|
515
540
|
---
|
|
516
541
|
|
|
@@ -535,8 +560,9 @@ frontend, a script).
|
|
|
535
560
|
|
|
536
561
|
Every endpoint is **staff-only by default** (or whatever
|
|
537
562
|
`AdminSite.has_permission` returns), CSRF-required on unsafe
|
|
538
|
-
methods, and emits `Cache-Control: no-store`. Full wire contract
|
|
539
|
-
|
|
563
|
+
methods, and emits `Cache-Control: no-store`. Full wire contract
|
|
564
|
+
lives in the API repo:
|
|
565
|
+
[`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api).
|
|
540
566
|
|
|
541
567
|
---
|
|
542
568
|
|
|
@@ -600,6 +626,10 @@ See [`SECURITY.md`](SECURITY.md). Do **not** open a public issue.
|
|
|
600
626
|
|
|
601
627
|
## Contributing
|
|
602
628
|
|
|
603
|
-
|
|
604
|
-
[
|
|
629
|
+
Open an [Issue](https://github.com/MartinCastroAlvarez/django-admin-react/issues/new)
|
|
630
|
+
or a [Discussion](https://github.com/MartinCastroAlvarez/django-admin-react/discussions)
|
|
631
|
+
before sending a PR for anything non-trivial. **API-side contributions** (any
|
|
632
|
+
`/api/v1/...` endpoint, the wire contract, permission gates, serializer
|
|
633
|
+
denylist) go to [`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api)
|
|
634
|
+
— this repo owns only the **React SPA super-layer** on top.
|
|
605
635
|
|
|
@@ -4,11 +4,42 @@ A drop-in **React single-page admin** for any Django 5+ project. Same
|
|
|
4
4
|
`pip install`, same `INSTALLED_APPS`, same `urls.py include()` — and
|
|
5
5
|
your `ModelAdmin` classes drive everything. No React code on your side.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
```python
|
|
8
|
+
# settings.py
|
|
9
|
+
INSTALLED_APPS = [
|
|
10
|
+
# ...
|
|
11
|
+
"django.contrib.admin",
|
|
12
|
+
"django_admin_rest_api", # the JSON REST API (sibling package — pulled in as a dependency)
|
|
13
|
+
"django_admin_react", # this package — the React SPA on top of it
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
# urls.py
|
|
17
|
+
urlpatterns = [
|
|
18
|
+
path("admin/", admin.site.urls),
|
|
19
|
+
path("admin-react/", include("django_admin_react.urls")), # SPA + its API include
|
|
20
|
+
]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> **Beta — v1.0.0.** Available on PyPI; the SPA + the API
|
|
24
|
+
> ([`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/))
|
|
25
|
+
> + the MCP adapter
|
|
26
|
+
> ([`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/))
|
|
27
|
+
> all share the v1 wire contract. Track progress on the
|
|
9
28
|
> [Project board](https://github.com/users/MartinCastroAlvarez/projects/3)
|
|
10
29
|
> and the [Issues list](https://github.com/MartinCastroAlvarez/django-admin-react/issues).
|
|
11
30
|
|
|
31
|
+
## Three repos, one product
|
|
32
|
+
|
|
33
|
+
The project is split into three independently-published, cross-referenced repos so each piece can be consumed on its own merits:
|
|
34
|
+
|
|
35
|
+
| Repo | PyPI | Role |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| **[`django-admin-rest-api`](https://github.com/MartinCastroAlvarez/django-admin-api)** | [`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/) | The JSON REST API for the Django admin — same permissions, same `ModelAdmin`, no new features. The wire surface. |
|
|
38
|
+
| **`django-admin-react`** *(this repo)* | [`django-admin-react`](https://pypi.org/project/django-admin-react/) | The React SPA frontend. A **super-layer** that depends on `django-admin-rest-api` for every wire call. |
|
|
39
|
+
| **[`django-admin-mcp-api`](https://github.com/MartinCastroAlvarez/django-admin-mcp)** | [`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/) | Wire-protocol-only **MCP** adapter (call, manifest, …) over `django-admin-rest-api` — lets agents reach the same `ModelAdmin`-driven REST surface, no new functionality / permissions / validation. |
|
|
40
|
+
|
|
41
|
+
The wire contract itself lives in the **API repo** (`docs/api-contract.md` there). This README is about the SPA. The migration from "self-contained" to the 3-repo split is tracked in [META #544](https://github.com/MartinCastroAlvarez/django-admin-react/issues/544).
|
|
42
|
+
|
|
12
43
|
---
|
|
13
44
|
|
|
14
45
|
## Why django-admin-react
|
|
@@ -46,8 +77,8 @@ permissions at runtime from `GET /api/v1/registry/`. Add a new
|
|
|
46
77
|
|
|
47
78
|
Real captures of the **django-admin-react SPA** rendering the bundled
|
|
48
79
|
`examples/` apps — driven entirely by each app's `ModelAdmin`.
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
Captured **manually** against a local dev server (no Playwright / Cypress /
|
|
81
|
+
e2e tooling required).
|
|
51
82
|
|
|
52
83
|
| Sign in (package login) | Registry / home |
|
|
53
84
|
| -------------------------------------------------- | ----------------------------------------------------- |
|
|
@@ -72,34 +103,16 @@ emails, account numbers, or PII).
|
|
|
72
103
|
pip install django-admin-react
|
|
73
104
|
```
|
|
74
105
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
INSTALLED_APPS
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"django.contrib.messages",
|
|
83
|
-
"django.contrib.staticfiles",
|
|
84
|
-
"django_admin_react", # ← add this
|
|
85
|
-
# ... your own apps
|
|
86
|
-
]
|
|
87
|
-
```
|
|
106
|
+
This pulls in the JSON API ([`django-admin-rest-api`](https://pypi.org/project/django-admin-rest-api/))
|
|
107
|
+
and the MCP adapter ([`django-admin-mcp-api`](https://pypi.org/project/django-admin-mcp-api/))
|
|
108
|
+
as transitive dependencies. The **two-line `INSTALLED_APPS` + one-line
|
|
109
|
+
URL include** at the top of this README is the *entire* integration.
|
|
110
|
+
Mount at any prefix you like — `/admin-react/`, `/staff/`,
|
|
111
|
+
`/back-office/` — just don't collide with `django.contrib.admin`'s
|
|
112
|
+
own mount.
|
|
88
113
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
from django.urls import include, path
|
|
92
|
-
|
|
93
|
-
urlpatterns = [
|
|
94
|
-
path("admin/", include("django_admin_react.urls")),
|
|
95
|
-
# any prefix is fine:
|
|
96
|
-
# path("admin-react/", include("django_admin_react.urls")),
|
|
97
|
-
# path("staff/", include("django_admin_react.urls")),
|
|
98
|
-
]
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
That is the entire integration. Log in as a staff user → modern,
|
|
102
|
-
Tailwind-styled SPA driven by your existing `ModelAdmin` classes.
|
|
114
|
+
Log in as a staff user → modern, Tailwind-styled SPA driven by your
|
|
115
|
+
existing `ModelAdmin` classes.
|
|
103
116
|
|
|
104
117
|
The wheel ships the **pre-built React bundle**. You do **not** need
|
|
105
118
|
Node, pnpm, or any frontend toolchain to install or run.
|
|
@@ -128,6 +141,16 @@ DJANGO_ADMIN_REACT = {
|
|
|
128
141
|
# active states. Hex only (validated);
|
|
129
142
|
# injected as the --dar-primary CSS var, so
|
|
130
143
|
# rebranding needs no React rebuild.
|
|
144
|
+
|
|
145
|
+
# Auth + API mount
|
|
146
|
+
"REACT_LOGIN": True, # bool — React-rendered login is the default;
|
|
147
|
+
# the SPA shell is served to anonymous users
|
|
148
|
+
# and posts to /api/v1/login/. Set False to
|
|
149
|
+
# opt back into the legacy admin HTML login.
|
|
150
|
+
"API_URL_PREFIX": None, # str | None — point the SPA at a separately-
|
|
151
|
+
# mounted django-admin-rest-api (e.g.
|
|
152
|
+
# "/api/api/v1/"). Default None keeps the
|
|
153
|
+
# inline include the package ships today.
|
|
131
154
|
}
|
|
132
155
|
```
|
|
133
156
|
|
|
@@ -431,8 +454,9 @@ register_field_type(MoneyField, vocab_type="decimal")
|
|
|
431
454
|
# code required.
|
|
432
455
|
```
|
|
433
456
|
|
|
434
|
-
|
|
435
|
-
|
|
457
|
+
Coining a brand-new `vocab_type` (with a matching SPA widget) is an
|
|
458
|
+
**API-repo** concern — open the issue at
|
|
459
|
+
[`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api).
|
|
436
460
|
|
|
437
461
|
### Pre-built `get_*` overrides still work
|
|
438
462
|
|
|
@@ -479,7 +503,6 @@ and the [project board](https://github.com/users/MartinCastroAlvarez/projects/3)
|
|
|
479
503
|
✅ = shipped in the current alpha. 🟡 = not yet built (tracked). This
|
|
480
504
|
column is the **backend** capability only — for which surfaces the React
|
|
481
505
|
UI renders today, see the [frontend tracker (#160)](https://github.com/MartinCastroAlvarez/django-admin-react/issues/160).
|
|
482
|
-
[`ACCEPTANCE.md`](ACCEPTANCE.md) carries the full criterion-by-criterion list.
|
|
483
506
|
|
|
484
507
|
---
|
|
485
508
|
|
|
@@ -504,8 +527,9 @@ frontend, a script).
|
|
|
504
527
|
|
|
505
528
|
Every endpoint is **staff-only by default** (or whatever
|
|
506
529
|
`AdminSite.has_permission` returns), CSRF-required on unsafe
|
|
507
|
-
methods, and emits `Cache-Control: no-store`. Full wire contract
|
|
508
|
-
|
|
530
|
+
methods, and emits `Cache-Control: no-store`. Full wire contract
|
|
531
|
+
lives in the API repo:
|
|
532
|
+
[`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api).
|
|
509
533
|
|
|
510
534
|
---
|
|
511
535
|
|
|
@@ -569,5 +593,9 @@ See [`SECURITY.md`](SECURITY.md). Do **not** open a public issue.
|
|
|
569
593
|
|
|
570
594
|
## Contributing
|
|
571
595
|
|
|
572
|
-
|
|
573
|
-
[
|
|
596
|
+
Open an [Issue](https://github.com/MartinCastroAlvarez/django-admin-react/issues/new)
|
|
597
|
+
or a [Discussion](https://github.com/MartinCastroAlvarez/django-admin-react/discussions)
|
|
598
|
+
before sending a PR for anything non-trivial. **API-side contributions** (any
|
|
599
|
+
`/api/v1/...` endpoint, the wire contract, permission gates, serializer
|
|
600
|
+
denylist) go to [`MartinCastroAlvarez/django-admin-api`](https://github.com/MartinCastroAlvarez/django-admin-api)
|
|
601
|
+
— this repo owns only the **React SPA super-layer** on top.
|
|
@@ -17,6 +17,8 @@ Public surface:
|
|
|
17
17
|
|
|
18
18
|
- :func:`object_log_entries` — the ``LogEntry`` queryset for one object,
|
|
19
19
|
newest-first, with the acting user pre-fetched.
|
|
20
|
+
- :func:`recent_actions_for_user` — the most recent ``LogEntry`` rows for
|
|
21
|
+
one user (the index "Recent actions" panel), newest-first.
|
|
20
22
|
"""
|
|
21
23
|
|
|
22
24
|
from __future__ import annotations
|
|
@@ -40,3 +42,17 @@ def object_log_entries(obj: Model) -> QuerySet[LogEntry]:
|
|
|
40
42
|
.select_related("user")
|
|
41
43
|
.order_by("-action_time")
|
|
42
44
|
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def recent_actions_for_user(user_pk: str | int, limit: int) -> QuerySet[LogEntry]:
|
|
48
|
+
"""Return the most recent ``LogEntry`` rows for one user, newest first.
|
|
49
|
+
|
|
50
|
+
The user-scoped counterpart of :func:`object_log_entries`: filtered by
|
|
51
|
+
the acting user and capped at ``limit`` — exactly how Django's admin
|
|
52
|
+
index "Recent actions" panel reads the log
|
|
53
|
+
(``LogEntry.objects.filter(user=...)``). Same get_queryset-rule
|
|
54
|
+
rationale as the module docstring: LogEntry is a framework audit
|
|
55
|
+
table, not a consumer model, so it is read directly here (outside
|
|
56
|
+
``api/``) rather than via ``ModelAdmin.get_queryset``.
|
|
57
|
+
"""
|
|
58
|
+
return LogEntry.objects.filter(user__pk=user_pk).order_by("-action_time")[:limit]
|
|
@@ -62,19 +62,20 @@ DEFAULTS: dict[str, Any] = {
|
|
|
62
62
|
# falls back to this default, since the value is written into a
|
|
63
63
|
# ``<style>`` block and must not be able to inject CSS.
|
|
64
64
|
"PRIMARY_COLOR": "#2563eb",
|
|
65
|
-
# ``REACT_LOGIN`` —
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
# (
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
|
|
65
|
+
# ``REACT_LOGIN`` — React-rendered login is the **default** so the
|
|
66
|
+
# SPA fully replaces the Django admin URL surface end-to-end (owner
|
|
67
|
+
# directive 2026-05-28). ``SpaIndexView`` serves the React shell to
|
|
68
|
+
# anonymous users (with the CSRF cookie set) and the in-SPA login
|
|
69
|
+
# form POSTs to the API package's ``/api/v1/login/``. A consumer
|
|
70
|
+
# who wants the legacy HTML-admin login back can opt out with
|
|
71
|
+
# ``"REACT_LOGIN": False`` — the package's own ``<mount>/login/``
|
|
72
|
+
# endpoint is still mounted in either mode. The auth *mechanism* is
|
|
73
|
+
# unchanged in both modes (Django's ``authenticate``/``login``
|
|
74
|
+
# behind the JSON endpoint); only the UI surface differs. The
|
|
75
|
+
# shell carries no user data — serving it to anonymous users
|
|
76
|
+
# discloses nothing the static bundle wouldn't, and every data API
|
|
77
|
+
# call still returns 403 until the user authenticates.
|
|
78
|
+
"REACT_LOGIN": True,
|
|
78
79
|
# PWA (Issue #86) — all optional; sane defaults make the manifest
|
|
79
80
|
# work with zero config. See ``django_admin_react/pwa.py`` +
|
|
80
81
|
# ``docs/ux/pwa.md``.
|
|
@@ -87,6 +88,17 @@ DEFAULTS: dict[str, Any] = {
|
|
|
87
88
|
# dicts. ``None`` (default) uses the shipped
|
|
88
89
|
# 192/512/maskable set under
|
|
89
90
|
# ``static/dar/icons/``.
|
|
91
|
+
# ``API_URL_PREFIX`` — absolute URL prefix the SPA calls for every
|
|
92
|
+
# JSON request (#559). Default ``None`` keeps the inline include the
|
|
93
|
+
# package ships today (`<spa-mount>/api/v1/`), so existing consumers
|
|
94
|
+
# are unaffected. Override when the consumer mounts
|
|
95
|
+
# ``django_admin_rest_api.urls`` separately and the SPA should talk
|
|
96
|
+
# to **that** mount instead — for example
|
|
97
|
+
# ``DJANGO_ADMIN_REACT = {"API_URL_PREFIX": "/api/api/v1/"}`` lets
|
|
98
|
+
# the SPA and any other client share a single REST mount. When set,
|
|
99
|
+
# `django_admin_react.urls` skips the inline `api/v1/` include so
|
|
100
|
+
# there is no double-mount.
|
|
101
|
+
"API_URL_PREFIX": None,
|
|
90
102
|
"PWA_NAME": None,
|
|
91
103
|
"PWA_SHORT_NAME": None,
|
|
92
104
|
"PWA_ICONS": None,
|
|
@@ -109,6 +121,7 @@ class _PackageSettings:
|
|
|
109
121
|
BRAND_LOGO_URL: str | None = DEFAULTS["BRAND_LOGO_URL"]
|
|
110
122
|
PRIMARY_COLOR: str = DEFAULTS["PRIMARY_COLOR"]
|
|
111
123
|
REACT_LOGIN: bool = DEFAULTS["REACT_LOGIN"]
|
|
124
|
+
API_URL_PREFIX: str | None = DEFAULTS["API_URL_PREFIX"]
|
|
112
125
|
PWA_NAME: str | None = DEFAULTS["PWA_NAME"]
|
|
113
126
|
PWA_SHORT_NAME: str | None = DEFAULTS["PWA_SHORT_NAME"]
|
|
114
127
|
PWA_ICONS: list[dict[str, str]] | None = DEFAULTS["PWA_ICONS"]
|
|
@@ -34,7 +34,11 @@ from django.shortcuts import render
|
|
|
34
34
|
from django.views.generic import View
|
|
35
35
|
|
|
36
36
|
from django_admin_react import conf as dar_conf
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
# Re-use the API package's admin-site lookup (this repo implements no
|
|
39
|
+
# API; the registry helper lives there). The PWA only needs the active
|
|
40
|
+
# `AdminSite.name` for the manifest's start URL.
|
|
41
|
+
from django_admin_rest_api.api.registry import get_admin_site
|
|
38
42
|
|
|
39
43
|
# Theme colours keyed by the resolved colour scheme. Kept here (not in
|
|
40
44
|
# the SPA's CSS-var system) because the manifest is rendered server-side
|