plain.admin 0.24.0__tar.gz → 0.25.1__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.
- {plain_admin-0.24.0 → plain_admin-0.25.1}/.gitignore +2 -0
- plain_admin-0.25.1/PKG-INFO +178 -0
- plain_admin-0.25.1/plain/admin/README.md +163 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/admin.js +6 -1
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/objects.py +52 -52
- {plain_admin-0.24.0 → plain_admin-0.25.1}/pyproject.toml +1 -1
- plain_admin-0.24.0/PKG-INFO +0 -316
- plain_admin-0.24.0/plain/admin/README.md +0 -301
- {plain_admin-0.24.0 → plain_admin-0.25.1}/LICENSE +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/README.md +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/admin.css +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/chart.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/jquery-3.6.1.slim.min.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/list.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/popper.min.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/admin/tippy-bundle.umd.min.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/assets/toolbar/toolbar.js +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/cards/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/cards/base.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/cards/charts.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/cards/tables.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/config.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/dates.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/default_settings.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/README.md +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/middleware.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/models.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/permissions.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/settings.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/urls.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/impersonate/views.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/middleware.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/README.md +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/core.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/middleware.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/urls.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/querystats/views.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/base.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/base.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/card.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/chart.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/table.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/delete.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/detail.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/index.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/list.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/page.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/search.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/UUID.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/bool.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/datetime.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/default.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/dict.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/get_display.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/img.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/list.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/model.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/queryset.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Checkbox.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/CheckboxField.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/FieldErrors.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Help.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Input.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/InputField.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Label.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Select.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/SelectField.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Submit.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Textarea.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/TextareaField.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/querystats/querystats.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/querystats/toolbar.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates/toolbar/toolbar.html +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/templates.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/toolbar.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/urls.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/base.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/models.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/registry.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/types.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/plain/admin/views/viewsets.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/app/settings.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/app/urls.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/app/users/migrations/0001_initial.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/app/users/migrations/__init__.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/app/users/models.py +0 -0
- {plain_admin-0.24.0 → plain_admin-0.25.1}/tests/test_admin.py +0 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: plain.admin
|
3
|
+
Version: 0.25.1
|
4
|
+
Summary: Admin dashboard and tools for Plain.
|
5
|
+
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
6
|
+
License-Expression: BSD-3-Clause
|
7
|
+
License-File: LICENSE
|
8
|
+
Requires-Python: >=3.11
|
9
|
+
Requires-Dist: plain-auth<1.0.0
|
10
|
+
Requires-Dist: plain-htmx<1.0.0
|
11
|
+
Requires-Dist: plain-tailwind<1.0.0
|
12
|
+
Requires-Dist: plain<1.0.0
|
13
|
+
Requires-Dist: sqlparse>=0.2.2
|
14
|
+
Description-Content-Type: text/markdown
|
15
|
+
|
16
|
+
# plain.admin
|
17
|
+
|
18
|
+
**Manage your app with a backend interface.**
|
19
|
+
|
20
|
+
The Plain Admin provides a combination of built-in views and the flexibility to create your own. You can use it to quickly get visibility into your app's data and to manage it.
|
21
|
+
|
22
|
+

|
23
|
+
|
24
|
+
## Installation
|
25
|
+
|
26
|
+
Install the `plain.admin` package and its dependencies.
|
27
|
+
|
28
|
+
```console
|
29
|
+
uv add plain.admin
|
30
|
+
```
|
31
|
+
|
32
|
+
The admin uses a combination of other Plain packages, most of which you will already have installed. Ultimately, your settings will look something like this:
|
33
|
+
|
34
|
+
```python
|
35
|
+
# app/settings.py
|
36
|
+
INSTALLED_PACKAGES = [
|
37
|
+
"plain.models",
|
38
|
+
"plain.tailwind",
|
39
|
+
"plain.auth",
|
40
|
+
"plain.sessions",
|
41
|
+
"plain.htmx",
|
42
|
+
"plain.admin",
|
43
|
+
"plain.elements",
|
44
|
+
# other packages...
|
45
|
+
]
|
46
|
+
|
47
|
+
AUTH_USER_MODEL = "users.User"
|
48
|
+
AUTH_LOGIN_URL = "login"
|
49
|
+
|
50
|
+
MIDDLEWARE = [
|
51
|
+
"plain.sessions.middleware.SessionMiddleware",
|
52
|
+
"plain.auth.middleware.AuthenticationMiddleware",
|
53
|
+
"plain.admin.AdminMiddleware",
|
54
|
+
]
|
55
|
+
```
|
56
|
+
|
57
|
+
Your User model is expected to have an `is_admin` field (or attribute) for checking who has permission to access the admin.
|
58
|
+
|
59
|
+
```python
|
60
|
+
# app/users/models.py
|
61
|
+
from plain import models
|
62
|
+
|
63
|
+
|
64
|
+
@models.register_model
|
65
|
+
class User(models.Model):
|
66
|
+
is_admin = models.BooleanField(default=False)
|
67
|
+
# other fields...
|
68
|
+
```
|
69
|
+
|
70
|
+
To make the admin accessible, add the `AdminRouter` to your root URLs.
|
71
|
+
|
72
|
+
```python
|
73
|
+
# app/urls.py
|
74
|
+
from plain.admin.urls import AdminRouter
|
75
|
+
from plain.urls import Router, include, path
|
76
|
+
|
77
|
+
from . import views
|
78
|
+
|
79
|
+
|
80
|
+
class AppRouter(Router):
|
81
|
+
namespace = ""
|
82
|
+
urls = [
|
83
|
+
include("admin/", AdminRouter),
|
84
|
+
path("login/", views.LoginView, name="login"),
|
85
|
+
path("logout/", LogoutView, name="logout"),
|
86
|
+
# other urls...
|
87
|
+
]
|
88
|
+
|
89
|
+
```
|
90
|
+
|
91
|
+
Optionally, you can add the admin toolbar to your base template. The toolbar will appear when `settings.DEBUG` or when `request.user.is_admin` (including in production!).
|
92
|
+
|
93
|
+
```html
|
94
|
+
<!-- app/templates/base.html -->
|
95
|
+
<!DOCTYPE html>
|
96
|
+
<html lang="en">
|
97
|
+
<head>
|
98
|
+
<meta charset="UTF-8">
|
99
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
100
|
+
<title>{{ html_title|default("My App") }}</title>
|
101
|
+
{% tailwind_css %}
|
102
|
+
</head>
|
103
|
+
<body>
|
104
|
+
{% block content required %}{% endblock %}
|
105
|
+
|
106
|
+
{% toolbar %}
|
107
|
+
</body>
|
108
|
+
</html>
|
109
|
+
```
|
110
|
+
|
111
|
+
## Admin viewsets
|
112
|
+
|
113
|
+
The most common use of the admin is to display and manage your `plain.models`. To do this, create a viewset with a set of inner views.
|
114
|
+
|
115
|
+
```python
|
116
|
+
# app/users/admin.py
|
117
|
+
from plain.admin.views import (
|
118
|
+
AdminModelDetailView,
|
119
|
+
AdminModelListView,
|
120
|
+
AdminModelUpdateView,
|
121
|
+
AdminViewset,
|
122
|
+
register_viewset,
|
123
|
+
)
|
124
|
+
from plain.models.forms import ModelForm
|
125
|
+
|
126
|
+
from .models import User
|
127
|
+
|
128
|
+
|
129
|
+
class UserForm(ModelForm):
|
130
|
+
class Meta:
|
131
|
+
model = User
|
132
|
+
fields = ["email"]
|
133
|
+
|
134
|
+
|
135
|
+
@register_viewset
|
136
|
+
class UserAdmin(AdminViewset):
|
137
|
+
class ListView(AdminModelListView):
|
138
|
+
model = User
|
139
|
+
fields = [
|
140
|
+
"id",
|
141
|
+
"email",
|
142
|
+
"created_at__date",
|
143
|
+
]
|
144
|
+
queryset_order = ["-created_at"]
|
145
|
+
search_fields = [
|
146
|
+
"email",
|
147
|
+
]
|
148
|
+
|
149
|
+
class DetailView(AdminModelDetailView):
|
150
|
+
model = User
|
151
|
+
|
152
|
+
class UpdateView(AdminModelUpdateView):
|
153
|
+
template_name = "admin/users/user_form.html"
|
154
|
+
model = User
|
155
|
+
form_class = UserForm
|
156
|
+
```
|
157
|
+
|
158
|
+
The [`AdminViewset`](./views/viewsets.py) will automatically recognize inner views named `ListView`, `CreateView`, `DetailView`, `UpdateView`, and `DeleteView`. It will interlink these views automatically in the UI and form success URLs. You can define additional views too, but you will need to implement a couple methods to hook them up.
|
159
|
+
|
160
|
+
## Admin cards
|
161
|
+
|
162
|
+
TODO
|
163
|
+
|
164
|
+
## Admin forms
|
165
|
+
|
166
|
+
TODO
|
167
|
+
|
168
|
+
## Toolbar
|
169
|
+
|
170
|
+
TODO
|
171
|
+
|
172
|
+
## Impersonate
|
173
|
+
|
174
|
+
TODO
|
175
|
+
|
176
|
+
## Querystats
|
177
|
+
|
178
|
+
TODO
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# plain.admin
|
2
|
+
|
3
|
+
**Manage your app with a backend interface.**
|
4
|
+
|
5
|
+
The Plain Admin provides a combination of built-in views and the flexibility to create your own. You can use it to quickly get visibility into your app's data and to manage it.
|
6
|
+
|
7
|
+

|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Install the `plain.admin` package and its dependencies.
|
12
|
+
|
13
|
+
```console
|
14
|
+
uv add plain.admin
|
15
|
+
```
|
16
|
+
|
17
|
+
The admin uses a combination of other Plain packages, most of which you will already have installed. Ultimately, your settings will look something like this:
|
18
|
+
|
19
|
+
```python
|
20
|
+
# app/settings.py
|
21
|
+
INSTALLED_PACKAGES = [
|
22
|
+
"plain.models",
|
23
|
+
"plain.tailwind",
|
24
|
+
"plain.auth",
|
25
|
+
"plain.sessions",
|
26
|
+
"plain.htmx",
|
27
|
+
"plain.admin",
|
28
|
+
"plain.elements",
|
29
|
+
# other packages...
|
30
|
+
]
|
31
|
+
|
32
|
+
AUTH_USER_MODEL = "users.User"
|
33
|
+
AUTH_LOGIN_URL = "login"
|
34
|
+
|
35
|
+
MIDDLEWARE = [
|
36
|
+
"plain.sessions.middleware.SessionMiddleware",
|
37
|
+
"plain.auth.middleware.AuthenticationMiddleware",
|
38
|
+
"plain.admin.AdminMiddleware",
|
39
|
+
]
|
40
|
+
```
|
41
|
+
|
42
|
+
Your User model is expected to have an `is_admin` field (or attribute) for checking who has permission to access the admin.
|
43
|
+
|
44
|
+
```python
|
45
|
+
# app/users/models.py
|
46
|
+
from plain import models
|
47
|
+
|
48
|
+
|
49
|
+
@models.register_model
|
50
|
+
class User(models.Model):
|
51
|
+
is_admin = models.BooleanField(default=False)
|
52
|
+
# other fields...
|
53
|
+
```
|
54
|
+
|
55
|
+
To make the admin accessible, add the `AdminRouter` to your root URLs.
|
56
|
+
|
57
|
+
```python
|
58
|
+
# app/urls.py
|
59
|
+
from plain.admin.urls import AdminRouter
|
60
|
+
from plain.urls import Router, include, path
|
61
|
+
|
62
|
+
from . import views
|
63
|
+
|
64
|
+
|
65
|
+
class AppRouter(Router):
|
66
|
+
namespace = ""
|
67
|
+
urls = [
|
68
|
+
include("admin/", AdminRouter),
|
69
|
+
path("login/", views.LoginView, name="login"),
|
70
|
+
path("logout/", LogoutView, name="logout"),
|
71
|
+
# other urls...
|
72
|
+
]
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
Optionally, you can add the admin toolbar to your base template. The toolbar will appear when `settings.DEBUG` or when `request.user.is_admin` (including in production!).
|
77
|
+
|
78
|
+
```html
|
79
|
+
<!-- app/templates/base.html -->
|
80
|
+
<!DOCTYPE html>
|
81
|
+
<html lang="en">
|
82
|
+
<head>
|
83
|
+
<meta charset="UTF-8">
|
84
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
85
|
+
<title>{{ html_title|default("My App") }}</title>
|
86
|
+
{% tailwind_css %}
|
87
|
+
</head>
|
88
|
+
<body>
|
89
|
+
{% block content required %}{% endblock %}
|
90
|
+
|
91
|
+
{% toolbar %}
|
92
|
+
</body>
|
93
|
+
</html>
|
94
|
+
```
|
95
|
+
|
96
|
+
## Admin viewsets
|
97
|
+
|
98
|
+
The most common use of the admin is to display and manage your `plain.models`. To do this, create a viewset with a set of inner views.
|
99
|
+
|
100
|
+
```python
|
101
|
+
# app/users/admin.py
|
102
|
+
from plain.admin.views import (
|
103
|
+
AdminModelDetailView,
|
104
|
+
AdminModelListView,
|
105
|
+
AdminModelUpdateView,
|
106
|
+
AdminViewset,
|
107
|
+
register_viewset,
|
108
|
+
)
|
109
|
+
from plain.models.forms import ModelForm
|
110
|
+
|
111
|
+
from .models import User
|
112
|
+
|
113
|
+
|
114
|
+
class UserForm(ModelForm):
|
115
|
+
class Meta:
|
116
|
+
model = User
|
117
|
+
fields = ["email"]
|
118
|
+
|
119
|
+
|
120
|
+
@register_viewset
|
121
|
+
class UserAdmin(AdminViewset):
|
122
|
+
class ListView(AdminModelListView):
|
123
|
+
model = User
|
124
|
+
fields = [
|
125
|
+
"id",
|
126
|
+
"email",
|
127
|
+
"created_at__date",
|
128
|
+
]
|
129
|
+
queryset_order = ["-created_at"]
|
130
|
+
search_fields = [
|
131
|
+
"email",
|
132
|
+
]
|
133
|
+
|
134
|
+
class DetailView(AdminModelDetailView):
|
135
|
+
model = User
|
136
|
+
|
137
|
+
class UpdateView(AdminModelUpdateView):
|
138
|
+
template_name = "admin/users/user_form.html"
|
139
|
+
model = User
|
140
|
+
form_class = UserForm
|
141
|
+
```
|
142
|
+
|
143
|
+
The [`AdminViewset`](./views/viewsets.py) will automatically recognize inner views named `ListView`, `CreateView`, `DetailView`, `UpdateView`, and `DeleteView`. It will interlink these views automatically in the UI and form success URLs. You can define additional views too, but you will need to implement a couple methods to hook them up.
|
144
|
+
|
145
|
+
## Admin cards
|
146
|
+
|
147
|
+
TODO
|
148
|
+
|
149
|
+
## Admin forms
|
150
|
+
|
151
|
+
TODO
|
152
|
+
|
153
|
+
## Toolbar
|
154
|
+
|
155
|
+
TODO
|
156
|
+
|
157
|
+
## Impersonate
|
158
|
+
|
159
|
+
TODO
|
160
|
+
|
161
|
+
## Querystats
|
162
|
+
|
163
|
+
TODO
|
@@ -58,8 +58,13 @@ jQuery(function($) {
|
|
58
58
|
// Column already has a link, so don't add another
|
59
59
|
return;
|
60
60
|
}
|
61
|
+
var autolinkUrl = $this.data("column-autolink");
|
62
|
+
if (!autolinkUrl) {
|
63
|
+
// No URL, so don't add a link
|
64
|
+
return;
|
65
|
+
}
|
61
66
|
var $link = $(document.createElement("a"));
|
62
|
-
$link.attr("href",
|
67
|
+
$link.attr("href", autolinkUrl);
|
63
68
|
$link.addClass("flex p-2 -m-2 text-white/80 hover:no-underline");
|
64
69
|
$(this).wrapInner($link);
|
65
70
|
})
|
@@ -144,29 +144,29 @@ class AdminListView(HTMXViewMixin, AdminView):
|
|
144
144
|
"admin/values/default.html",
|
145
145
|
]
|
146
146
|
|
147
|
-
def get_list_url(self) -> str
|
148
|
-
return
|
147
|
+
def get_list_url(self) -> str:
|
148
|
+
return ""
|
149
149
|
|
150
|
-
def get_create_url(self) -> str
|
151
|
-
return
|
150
|
+
def get_create_url(self) -> str:
|
151
|
+
return ""
|
152
152
|
|
153
|
-
def get_detail_url(self, obj) -> str
|
154
|
-
return
|
153
|
+
def get_detail_url(self, obj) -> str:
|
154
|
+
return ""
|
155
155
|
|
156
|
-
def get_update_url(self, obj) -> str
|
157
|
-
return
|
156
|
+
def get_update_url(self, obj) -> str:
|
157
|
+
return ""
|
158
158
|
|
159
|
-
def get_delete_url(self, obj) -> str
|
160
|
-
return
|
159
|
+
def get_delete_url(self, obj) -> str:
|
160
|
+
return ""
|
161
161
|
|
162
|
-
def get_object_url(self, obj) -> str
|
162
|
+
def get_object_url(self, obj) -> str:
|
163
163
|
if url := self.get_detail_url(obj):
|
164
164
|
return url
|
165
165
|
if url := self.get_update_url(obj):
|
166
166
|
return url
|
167
167
|
if url := self.get_delete_url(obj):
|
168
168
|
return url
|
169
|
-
return
|
169
|
+
return ""
|
170
170
|
|
171
171
|
def get_object_links(self, obj) -> dict[str]:
|
172
172
|
links = {}
|
@@ -191,20 +191,20 @@ class AdminListView(HTMXViewMixin, AdminView):
|
|
191
191
|
class AdminCreateView(AdminView, CreateView):
|
192
192
|
template_name = None
|
193
193
|
|
194
|
-
def get_list_url(self) -> str
|
195
|
-
return
|
194
|
+
def get_list_url(self) -> str:
|
195
|
+
return ""
|
196
196
|
|
197
|
-
def get_create_url(self) -> str
|
198
|
-
return
|
197
|
+
def get_create_url(self) -> str:
|
198
|
+
return ""
|
199
199
|
|
200
|
-
def get_detail_url(self, obj) -> str
|
201
|
-
return
|
200
|
+
def get_detail_url(self, obj) -> str:
|
201
|
+
return ""
|
202
202
|
|
203
|
-
def get_update_url(self, obj) -> str
|
204
|
-
return
|
203
|
+
def get_update_url(self, obj) -> str:
|
204
|
+
return ""
|
205
205
|
|
206
|
-
def get_delete_url(self, obj) -> str
|
207
|
-
return
|
206
|
+
def get_delete_url(self, obj) -> str:
|
207
|
+
return ""
|
208
208
|
|
209
209
|
def get_success_url(self, form):
|
210
210
|
if list_url := self.get_list_url():
|
@@ -274,20 +274,20 @@ class AdminDetailView(AdminView, DetailView):
|
|
274
274
|
|
275
275
|
return templates
|
276
276
|
|
277
|
-
def get_list_url(self) -> str
|
278
|
-
return
|
277
|
+
def get_list_url(self) -> str:
|
278
|
+
return ""
|
279
279
|
|
280
|
-
def get_create_url(self) -> str
|
281
|
-
return
|
280
|
+
def get_create_url(self) -> str:
|
281
|
+
return ""
|
282
282
|
|
283
|
-
def get_detail_url(self, obj) -> str
|
284
|
-
return
|
283
|
+
def get_detail_url(self, obj) -> str:
|
284
|
+
return ""
|
285
285
|
|
286
|
-
def get_update_url(self, obj) -> str
|
287
|
-
return
|
286
|
+
def get_update_url(self, obj) -> str:
|
287
|
+
return ""
|
288
288
|
|
289
|
-
def get_delete_url(self, obj) -> str
|
290
|
-
return
|
289
|
+
def get_delete_url(self, obj) -> str:
|
290
|
+
return ""
|
291
291
|
|
292
292
|
def get_fields(self):
|
293
293
|
return self.fields.copy() # Avoid mutating the class attribute itself
|
@@ -311,20 +311,20 @@ class AdminUpdateView(AdminView, UpdateView):
|
|
311
311
|
template_name = None
|
312
312
|
nav_section = ""
|
313
313
|
|
314
|
-
def get_list_url(self) -> str
|
315
|
-
return
|
314
|
+
def get_list_url(self) -> str:
|
315
|
+
return ""
|
316
316
|
|
317
|
-
def get_create_url(self) -> str
|
318
|
-
return
|
317
|
+
def get_create_url(self) -> str:
|
318
|
+
return ""
|
319
319
|
|
320
|
-
def get_detail_url(self, obj) -> str
|
321
|
-
return
|
320
|
+
def get_detail_url(self, obj) -> str:
|
321
|
+
return ""
|
322
322
|
|
323
|
-
def get_update_url(self, obj) -> str
|
324
|
-
return
|
323
|
+
def get_update_url(self, obj) -> str:
|
324
|
+
return ""
|
325
325
|
|
326
|
-
def get_delete_url(self, obj) -> str
|
327
|
-
return
|
326
|
+
def get_delete_url(self, obj) -> str:
|
327
|
+
return ""
|
328
328
|
|
329
329
|
def get_description(self):
|
330
330
|
return repr(self.object)
|
@@ -363,20 +363,20 @@ class AdminDeleteView(AdminView, DeleteView):
|
|
363
363
|
def get_description(self):
|
364
364
|
return repr(self.object)
|
365
365
|
|
366
|
-
def get_list_url(self) -> str
|
367
|
-
return
|
366
|
+
def get_list_url(self) -> str:
|
367
|
+
return ""
|
368
368
|
|
369
|
-
def get_create_url(self) -> str
|
370
|
-
return
|
369
|
+
def get_create_url(self) -> str:
|
370
|
+
return ""
|
371
371
|
|
372
|
-
def get_detail_url(self, obj) -> str
|
373
|
-
return
|
372
|
+
def get_detail_url(self, obj) -> str:
|
373
|
+
return ""
|
374
374
|
|
375
|
-
def get_update_url(self, obj) -> str
|
376
|
-
return
|
375
|
+
def get_update_url(self, obj) -> str:
|
376
|
+
return ""
|
377
377
|
|
378
|
-
def get_delete_url(self, obj) -> str
|
379
|
-
return
|
378
|
+
def get_delete_url(self, obj) -> str:
|
379
|
+
return ""
|
380
380
|
|
381
381
|
def get_links(self):
|
382
382
|
links = super().get_links()
|