django-admin-autoapi 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_autoapi-0.1.0/LICENSE +21 -0
- django_admin_autoapi-0.1.0/PKG-INFO +386 -0
- django_admin_autoapi-0.1.0/README.md +344 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/__init__.py +11 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/apps.py +11 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/authentication.py +66 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/mixins.py +291 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/pagination.py +39 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/serializers.py +79 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/sites.py +310 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/urls.py +39 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi/views.py +71 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi.egg-info/PKG-INFO +386 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi.egg-info/SOURCES.txt +19 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi.egg-info/dependency_links.txt +1 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi.egg-info/requires.txt +12 -0
- django_admin_autoapi-0.1.0/django_admin_autoapi.egg-info/top_level.txt +1 -0
- django_admin_autoapi-0.1.0/pyproject.toml +98 -0
- django_admin_autoapi-0.1.0/setup.cfg +4 -0
- django_admin_autoapi-0.1.0/setup.py +6 -0
- django_admin_autoapi-0.1.0/tests/test_api.py +366 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Chris Spence
|
|
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.
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-admin-autoapi
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Zero-config REST API generation for Django Admin
|
|
5
|
+
Author-email: Chris Spence <chris@example.com>
|
|
6
|
+
Maintainer-email: Chris Spence <chris@example.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/chrisspen/django-admin-autoapi
|
|
9
|
+
Project-URL: Documentation, https://github.com/chrisspen/django-admin-autoapi#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/chrisspen/django-admin-autoapi.git
|
|
11
|
+
Project-URL: Issues, https://github.com/chrisspen/django-admin-autoapi/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/chrisspen/django-admin-autoapi/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: django,admin,rest,api,automatic,zero-config
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Framework :: Django
|
|
17
|
+
Classifier: Framework :: Django :: 4.2
|
|
18
|
+
Classifier: Framework :: Django :: 5.0
|
|
19
|
+
Classifier: Intended Audience :: Developers
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.11
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: Django>=4.2
|
|
31
|
+
Requires-Dist: djangorestframework>=3.14
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-django>=4.5; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
37
|
+
Requires-Dist: isort>=5.12; extra == "dev"
|
|
38
|
+
Requires-Dist: flake8>=6.0; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
40
|
+
Requires-Dist: tox>=4.0; extra == "dev"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
<div align="center">
|
|
44
|
+
<img src="./assets/logo-clear2-medium.png" alt="django-admin-autoapi logo">
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# django-admin-autoapi
|
|
49
|
+
|
|
50
|
+
Zero-configuration REST API generation for Django Admin. Automatically expose your admin-registered models via a REST API with token authentication and Django model permissions.
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Zero Configuration**: Models registered with the admin are automatically available via REST API
|
|
55
|
+
- **Token Authentication**: Uses Django REST Framework's token authentication
|
|
56
|
+
- **Permission Integration**: Leverages Django's built-in model permissions (view, add, change, delete)
|
|
57
|
+
- **Field Selection**: Request only the fields you need with `?fields=name,email`
|
|
58
|
+
- **Filtering**: Filter querysets with query parameters like `?status=published`
|
|
59
|
+
- **Ordering**: Sort results with `?order_by=name` or `?order_by=-created_at`
|
|
60
|
+
- **Pagination**: Built-in pagination with configurable page size
|
|
61
|
+
- **Calculated Fields**: Expose model properties via `api_calculated_fields`
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install django-admin-autoapi
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Add to your `INSTALLED_APPS`:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
INSTALLED_APPS = [
|
|
73
|
+
# Django apps
|
|
74
|
+
"django.contrib.admin",
|
|
75
|
+
"django.contrib.auth",
|
|
76
|
+
"django.contrib.contenttypes",
|
|
77
|
+
# ...
|
|
78
|
+
|
|
79
|
+
# Required
|
|
80
|
+
"rest_framework",
|
|
81
|
+
"rest_framework.authtoken",
|
|
82
|
+
"django_admin_autoapi",
|
|
83
|
+
|
|
84
|
+
# Your apps
|
|
85
|
+
"myapp",
|
|
86
|
+
]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Configure Django REST Framework:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
REST_FRAMEWORK = {
|
|
93
|
+
"DEFAULT_AUTHENTICATION_CLASSES": [
|
|
94
|
+
"rest_framework.authentication.TokenAuthentication",
|
|
95
|
+
"rest_framework.authentication.SessionAuthentication",
|
|
96
|
+
],
|
|
97
|
+
"DEFAULT_PERMISSION_CLASSES": [
|
|
98
|
+
"rest_framework.permissions.IsAuthenticated",
|
|
99
|
+
],
|
|
100
|
+
"PAGE_SIZE": 25,
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Usage
|
|
105
|
+
|
|
106
|
+
### Basic Setup
|
|
107
|
+
|
|
108
|
+
Replace Django's default admin site with the AutoAPI admin site:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
# myapp/admin.py
|
|
112
|
+
from django.contrib import admin
|
|
113
|
+
from django_admin_autoapi.sites import site
|
|
114
|
+
|
|
115
|
+
from .models import Author, Book
|
|
116
|
+
|
|
117
|
+
# Register models with the AutoAPI admin site
|
|
118
|
+
site.register(Author)
|
|
119
|
+
site.register(Book)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Update your URL configuration:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# urls.py
|
|
126
|
+
from django_admin_autoapi.sites import site
|
|
127
|
+
|
|
128
|
+
urlpatterns = [
|
|
129
|
+
path("admin/", site.urls),
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
That's it! Your models are now available via REST API at:
|
|
134
|
+
|
|
135
|
+
- `GET /admin/api/` - List all available endpoints
|
|
136
|
+
- `GET /admin/api/myapp/author/` - List authors
|
|
137
|
+
- `GET /admin/api/myapp/author/123/` - Retrieve author 123
|
|
138
|
+
- `POST /admin/api/myapp/author/` - Create author
|
|
139
|
+
- `PATCH /admin/api/myapp/author/123/` - Update author 123
|
|
140
|
+
- `DELETE /admin/api/myapp/author/123/` - Delete author 123
|
|
141
|
+
|
|
142
|
+
### Authentication
|
|
143
|
+
|
|
144
|
+
Get a token for a user:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Create a token (in Django shell or via management command)
|
|
148
|
+
from rest_framework.authtoken.models import Token
|
|
149
|
+
token = Token.objects.create(user=user)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Use the token in API requests:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
curl -H "Authorization: Token your-token-here" \
|
|
156
|
+
http://localhost:8000/admin/api/myapp/author/
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Field Selection
|
|
160
|
+
|
|
161
|
+
Request only specific fields:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Only get id, name, and email
|
|
165
|
+
curl -H "Authorization: Token ..." \
|
|
166
|
+
"http://localhost:8000/admin/api/myapp/author/?fields=name,email"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Filtering
|
|
170
|
+
|
|
171
|
+
Filter results with query parameters:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Filter by status
|
|
175
|
+
curl -H "Authorization: Token ..." \
|
|
176
|
+
"http://localhost:8000/admin/api/myapp/book/?status=published"
|
|
177
|
+
|
|
178
|
+
# Filter by related field
|
|
179
|
+
curl -H "Authorization: Token ..." \
|
|
180
|
+
"http://localhost:8000/admin/api/myapp/book/?author=123"
|
|
181
|
+
|
|
182
|
+
# Django-style lookups
|
|
183
|
+
curl -H "Authorization: Token ..." \
|
|
184
|
+
"http://localhost:8000/admin/api/myapp/book/?title__contains=Django"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Ordering
|
|
188
|
+
|
|
189
|
+
Sort results:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Sort by name ascending
|
|
193
|
+
curl -H "Authorization: Token ..." \
|
|
194
|
+
"http://localhost:8000/admin/api/myapp/author/?order_by=name"
|
|
195
|
+
|
|
196
|
+
# Sort by created_at descending
|
|
197
|
+
curl -H "Authorization: Token ..." \
|
|
198
|
+
"http://localhost:8000/admin/api/myapp/author/?order_by=-created_at"
|
|
199
|
+
|
|
200
|
+
# Multiple fields
|
|
201
|
+
curl -H "Authorization: Token ..." \
|
|
202
|
+
"http://localhost:8000/admin/api/myapp/book/?order_by=author,-title"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Calculated Fields
|
|
206
|
+
|
|
207
|
+
Expose model properties in the API:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
class Author(models.Model):
|
|
211
|
+
first_name = models.CharField(max_length=100)
|
|
212
|
+
last_name = models.CharField(max_length=100)
|
|
213
|
+
email = models.EmailField()
|
|
214
|
+
|
|
215
|
+
# List properties to expose via API
|
|
216
|
+
api_calculated_fields = ["full_name", "display_name"]
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def full_name(self):
|
|
220
|
+
return f"{self.first_name} {self.last_name}"
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
def display_name(self):
|
|
224
|
+
return f"{self.full_name} <{self.email}>"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Custom Admin Classes
|
|
228
|
+
|
|
229
|
+
Use the mixin with custom ModelAdmin classes:
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
from django.contrib import admin
|
|
233
|
+
from django_admin_autoapi.sites import site
|
|
234
|
+
from django_admin_autoapi.mixins import AutoAPIMixin
|
|
235
|
+
|
|
236
|
+
class AuthorAdmin(AutoAPIMixin, admin.ModelAdmin):
|
|
237
|
+
list_display = ["name", "email", "is_active"]
|
|
238
|
+
list_filter = ["is_active"]
|
|
239
|
+
search_fields = ["name", "email"]
|
|
240
|
+
|
|
241
|
+
site.register(Author, AuthorAdmin)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Read-Only API
|
|
245
|
+
|
|
246
|
+
For read-only API access, use the read-only mixin:
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from django_admin_autoapi.mixins import ReadOnlyAutoAPIMixin
|
|
250
|
+
|
|
251
|
+
class ReportAdmin(ReadOnlyAutoAPIMixin, admin.ModelAdmin):
|
|
252
|
+
list_display = ["title", "created_at"]
|
|
253
|
+
|
|
254
|
+
site.register(Report, ReportAdmin)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Permissions
|
|
258
|
+
|
|
259
|
+
The API respects Django's built-in model permissions:
|
|
260
|
+
|
|
261
|
+
| HTTP Method | Required Permission |
|
|
262
|
+
|------------|---------------------|
|
|
263
|
+
| GET | `app.view_model` |
|
|
264
|
+
| POST | `app.add_model` |
|
|
265
|
+
| PUT/PATCH | `app.change_model` |
|
|
266
|
+
| DELETE | `app.delete_model` |
|
|
267
|
+
|
|
268
|
+
Users must have `is_staff=True` and the appropriate permissions to access the API.
|
|
269
|
+
|
|
270
|
+
## Pagination
|
|
271
|
+
|
|
272
|
+
Responses are paginated by default:
|
|
273
|
+
|
|
274
|
+
```json
|
|
275
|
+
{
|
|
276
|
+
"count": 100,
|
|
277
|
+
"next": "http://localhost:8000/admin/api/myapp/author/?page=2",
|
|
278
|
+
"previous": null,
|
|
279
|
+
"results": [
|
|
280
|
+
{"id": 1, "name": "Author 1", ...},
|
|
281
|
+
{"id": 2, "name": "Author 2", ...},
|
|
282
|
+
...
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Configure pagination in settings:
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
REST_FRAMEWORK = {
|
|
291
|
+
"PAGE_SIZE": 25, # Default items per page
|
|
292
|
+
"MAX_PAGE_SIZE": 1000, # Maximum items per page
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Request a specific page size:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
curl "http://localhost:8000/admin/api/myapp/author/?limit=50"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## API Index
|
|
303
|
+
|
|
304
|
+
Get a list of all available endpoints:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
curl -H "Authorization: Token ..." \
|
|
308
|
+
http://localhost:8000/admin/api/
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Response:
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"endpoints": [
|
|
316
|
+
{
|
|
317
|
+
"model": "myapp.author",
|
|
318
|
+
"list_url": "/admin/api/myapp/author/",
|
|
319
|
+
"detail_url": "/admin/api/myapp/author/<pk>/",
|
|
320
|
+
"verbose_name": "author",
|
|
321
|
+
"verbose_name_plural": "authors"
|
|
322
|
+
},
|
|
323
|
+
...
|
|
324
|
+
],
|
|
325
|
+
"count": 5
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Configuration
|
|
330
|
+
|
|
331
|
+
### Custom Admin Site Name
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
from django_admin_autoapi.sites import AutoAPIAdminSite
|
|
335
|
+
|
|
336
|
+
site = AutoAPIAdminSite(name="myadmin")
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Disable API for Specific Models
|
|
340
|
+
|
|
341
|
+
Register with the standard Django admin instead of the AutoAPI site:
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
from django.contrib import admin
|
|
345
|
+
from django_admin_autoapi.sites import site
|
|
346
|
+
|
|
347
|
+
# This model gets an API
|
|
348
|
+
site.register(PublicModel)
|
|
349
|
+
|
|
350
|
+
# This model doesn't get an API
|
|
351
|
+
admin.site.register(InternalModel)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Requirements
|
|
355
|
+
|
|
356
|
+
- Python 3.11+
|
|
357
|
+
- Django 4.2+
|
|
358
|
+
- Django REST Framework 3.14+
|
|
359
|
+
|
|
360
|
+
## Development
|
|
361
|
+
|
|
362
|
+
Run tests across Python and Django versions:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
./test.sh
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Or run a specific environment:
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
./test.sh -e py312-django50
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Available test environments:
|
|
375
|
+
- `py311-django42` - Python 3.11 + Django 4.2
|
|
376
|
+
- `py311-django50` - Python 3.11 + Django 5.0
|
|
377
|
+
- `py312-django42` - Python 3.12 + Django 4.2
|
|
378
|
+
- `py312-django50` - Python 3.12 + Django 5.0
|
|
379
|
+
|
|
380
|
+
## License
|
|
381
|
+
|
|
382
|
+
MIT License - see LICENSE file for details.
|
|
383
|
+
|
|
384
|
+
## Contributing
|
|
385
|
+
|
|
386
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|