plain.admin 0.25.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.
Files changed (91) hide show
  1. {plain_admin-0.25.0 → plain_admin-0.25.1}/.gitignore +2 -0
  2. plain_admin-0.25.1/PKG-INFO +178 -0
  3. plain_admin-0.25.1/plain/admin/README.md +163 -0
  4. {plain_admin-0.25.0 → plain_admin-0.25.1}/pyproject.toml +1 -1
  5. plain_admin-0.25.0/PKG-INFO +0 -316
  6. plain_admin-0.25.0/plain/admin/README.md +0 -301
  7. {plain_admin-0.25.0 → plain_admin-0.25.1}/LICENSE +0 -0
  8. {plain_admin-0.25.0 → plain_admin-0.25.1}/README.md +0 -0
  9. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/__init__.py +0 -0
  10. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/admin.css +0 -0
  11. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/admin.js +0 -0
  12. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/chart.js +0 -0
  13. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/jquery-3.6.1.slim.min.js +0 -0
  14. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/list.js +0 -0
  15. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/popper.min.js +0 -0
  16. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/admin/tippy-bundle.umd.min.js +0 -0
  17. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/assets/toolbar/toolbar.js +0 -0
  18. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/cards/__init__.py +0 -0
  19. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/cards/base.py +0 -0
  20. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/cards/charts.py +0 -0
  21. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/cards/tables.py +0 -0
  22. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/config.py +0 -0
  23. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/dates.py +0 -0
  24. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/default_settings.py +0 -0
  25. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/README.md +0 -0
  26. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/__init__.py +0 -0
  27. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/middleware.py +0 -0
  28. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/models.py +0 -0
  29. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/permissions.py +0 -0
  30. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/settings.py +0 -0
  31. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/urls.py +0 -0
  32. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/impersonate/views.py +0 -0
  33. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/middleware.py +0 -0
  34. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/README.md +0 -0
  35. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/__init__.py +0 -0
  36. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/core.py +0 -0
  37. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/middleware.py +0 -0
  38. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/urls.py +0 -0
  39. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/querystats/views.py +0 -0
  40. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/base.html +0 -0
  41. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/base.html +0 -0
  42. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/card.html +0 -0
  43. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/chart.html +0 -0
  44. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/cards/table.html +0 -0
  45. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/delete.html +0 -0
  46. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/detail.html +0 -0
  47. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/index.html +0 -0
  48. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/list.html +0 -0
  49. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/page.html +0 -0
  50. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/search.html +0 -0
  51. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/UUID.html +0 -0
  52. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/bool.html +0 -0
  53. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/datetime.html +0 -0
  54. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/default.html +0 -0
  55. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/dict.html +0 -0
  56. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/get_display.html +0 -0
  57. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/img.html +0 -0
  58. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/list.html +0 -0
  59. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/model.html +0 -0
  60. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/admin/values/queryset.html +0 -0
  61. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Checkbox.html +0 -0
  62. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/CheckboxField.html +0 -0
  63. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/FieldErrors.html +0 -0
  64. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Help.html +0 -0
  65. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Input.html +0 -0
  66. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/InputField.html +0 -0
  67. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Label.html +0 -0
  68. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Select.html +0 -0
  69. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/SelectField.html +0 -0
  70. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Submit.html +0 -0
  71. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/Textarea.html +0 -0
  72. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/elements/admin/TextareaField.html +0 -0
  73. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/querystats/querystats.html +0 -0
  74. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/querystats/toolbar.html +0 -0
  75. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates/toolbar/toolbar.html +0 -0
  76. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/templates.py +0 -0
  77. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/toolbar.py +0 -0
  78. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/urls.py +0 -0
  79. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/__init__.py +0 -0
  80. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/base.py +0 -0
  81. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/models.py +0 -0
  82. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/objects.py +0 -0
  83. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/registry.py +0 -0
  84. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/types.py +0 -0
  85. {plain_admin-0.25.0 → plain_admin-0.25.1}/plain/admin/views/viewsets.py +0 -0
  86. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/app/settings.py +0 -0
  87. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/app/urls.py +0 -0
  88. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/app/users/migrations/0001_initial.py +0 -0
  89. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/app/users/migrations/__init__.py +0 -0
  90. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/app/users/models.py +0 -0
  91. {plain_admin-0.25.0 → plain_admin-0.25.1}/tests/test_admin.py +0 -0
@@ -11,3 +11,5 @@ plain*/tests/.plain
11
11
 
12
12
  # Ottobot
13
13
  .aider*
14
+
15
+ /llms-full.txt
@@ -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
+ ![Plain Admin user example](https://assets.plainframework.com/docs/plain-pageviews-user.png)
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
+ ![Plain Admin user example](https://assets.plainframework.com/docs/plain-pageviews-user.png)
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain.admin"
3
- version = "0.25.0"
3
+ version = "0.25.1"
4
4
  description = "Admin dashboard and tools for Plain."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  license = "BSD-3-Clause"
@@ -1,316 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: plain.admin
3
- Version: 0.25.0
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
- # Admin
17
-
18
- An admin interface for admin users.
19
-
20
- The Plain Admin is a new package built from the ground up.
21
- It leverages class-based views and standard URLs and templates to provide a flexible admin where
22
- you can quickly create your own pages and cards,
23
- in addition to models.
24
-
25
- - cards
26
- - dashboards
27
- - diy forms - have to install elements if you want to use them (or an app uses them, or maybe plain pkgs should use them just for admin...)
28
- - detached from login (do your own login (oauth, passkeys, etc))
29
-
30
- ## Installation
31
-
32
- - install plain.admin and plain.htmx, add plain.admin.admin and plain.htmx to installed packages
33
-
34
- Add the `AdminRouter` to your `urls.py`.
35
-
36
- ```python
37
- # app/urls.py
38
- from plain.admin.urls import AdminRouter
39
- from plain.urls import Router, include, path
40
-
41
- from . import views
42
-
43
-
44
- class AppRouter(Router):
45
- namespace = ""
46
- urls = [
47
- include("admin/", AdminRouter),
48
- path("login/", views.LoginView, name="login"),
49
- path("logout/", LogoutView, name="logout"),
50
- # Your other urls here...
51
- ]
52
-
53
- ```
54
-
55
- Optionally, add the admin toolbar to your base template.
56
-
57
- ```html
58
- <!-- app/templates/base.html -->
59
- <!DOCTYPE html>
60
- <html lang="en">
61
- <head>
62
- <meta charset="UTF-8">
63
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
64
- <title>{{ html_title|default("My App") }}</title>
65
- {% tailwind_css %}
66
- </head>
67
- <body>
68
- {% block content required %}{% endblock %}
69
-
70
- {% toolbar %}
71
- </body>
72
- </html>
73
- ```
74
-
75
- ## Models in the admin
76
-
77
- ## Dashboards
78
-
79
- <!-- # plain.querystats
80
-
81
- On-page database query stats in development and production.
82
-
83
- On each page, the query stats will display how many database queries were performed and how long they took.
84
-
85
- [Watch on YouTube](https://www.youtube.com/watch?v=NX8VXxVJm08)
86
-
87
- Clicking the stats in the toolbar will show the full SQL query log with tracebacks and timings.
88
- This is even designed to work in production,
89
- making it much easier to discover and debug performance issues on production data!
90
-
91
- ![Django query stats](https://user-images.githubusercontent.com/649496/213781593-54197bb6-36a8-4c9d-8294-5b43bd86a4c9.png)
92
-
93
- It will also point out duplicate queries,
94
- which can typically be removed by using `select_related`,
95
- `prefetch_related`, or otherwise refactoring your code.
96
-
97
- ## Installation
98
-
99
- ```python
100
- # settings.py
101
- INSTALLED_PACKAGES = [
102
- # ...
103
- "plain.admin.querystats",
104
- ]
105
-
106
- MIDDLEWARE = [
107
- "plain.sessions.middleware.SessionMiddleware",
108
- "plain.auth.middleware.AuthenticationMiddleware",
109
-
110
- "plain.admin.querystats.QueryStatsMiddleware",
111
- # Put additional middleware below querystats
112
- # ...
113
- ]
114
- ```
115
-
116
- We strongly recommend using the plain-toolbar along with this,
117
- but if you aren't,
118
- you can add the querystats to your frontend templates with this include:
119
-
120
- ```html
121
- {% include "querystats/button.html" %}
122
- ```
123
-
124
- *Note that you will likely want to surround this with an if `DEBUG` or `is_admin` check.*
125
-
126
- To view querystats you need to send a POST request to `?querystats=store` (i.e. via a `<form>`),
127
- and the template include is the easiest way to do that.
128
-
129
- ## Tailwind CSS
130
-
131
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
132
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
133
-
134
- If you are using your own Tailwind implementation,
135
- you can modify the "content" in your Tailwind config to include any Plain packages:
136
-
137
- ```js
138
- // tailwind.config.js
139
- module.exports = {
140
- content: [
141
- // ...
142
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
143
- ],
144
- // ...
145
- }
146
- ```
147
-
148
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
149
-
150
-
151
- # plain.toolbar
152
-
153
- The admin toolbar is enabled for every user who `is_admin`.
154
-
155
- ![Plain Admin toolbar](https://user-images.githubusercontent.com/649496/213781915-a2094f54-99b8-4a05-a36e-dee107405229.png)
156
-
157
- ## Installation
158
-
159
- Add `plaintoolbar` to your `INSTALLED_PACKAGES`,
160
- and the `{% toolbar %}` to your base template:
161
-
162
- ```python
163
- # settings.py
164
- INSTALLED_PACKAGES += [
165
- "plaintoolbar",
166
- ]
167
- ```
168
-
169
- ```html
170
- <!-- base.template.html -->
171
-
172
- {% load toolbar %}
173
-
174
- <!doctype html>
175
- <html lang="en">
176
- <head>
177
- ...
178
- </head>
179
- <body>
180
- {% toolbar %}
181
- ...
182
- </body>
183
- ```
184
-
185
- More specific settings can be found below.
186
-
187
- ## Tailwind CSS
188
-
189
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
190
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
191
-
192
- If you are using your own Tailwind implementation,
193
- you can modify the "content" in your Tailwind config to include any Plain packages:
194
-
195
- ```js
196
- // tailwind.config.js
197
- module.exports = {
198
- content: [
199
- // ...
200
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
201
- ],
202
- // ...
203
- }
204
- ```
205
-
206
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
207
-
208
- # plain.requestlog
209
-
210
- The request log stores a local history of HTTP requests and responses during `plain work` (Django runserver).
211
-
212
- The request history will make it easy to see redirects,
213
- 400 and 500 level errors,
214
- form submissions,
215
- API calls,
216
- webhooks,
217
- and more.
218
-
219
- [Watch on YouTube](https://www.youtube.com/watch?v=AwI7Pt5oZnM)
220
-
221
- Requests can be re-submitted by clicking the "replay" button.
222
-
223
- [![Django request log](https://user-images.githubusercontent.com/649496/213781414-417ad043-de67-4836-9ef1-2b91404336c3.png)](https://user-images.githubusercontent.com/649496/213781414-417ad043-de67-4836-9ef1-2b91404336c3.png)
224
-
225
- ## Installation
226
-
227
- ```python
228
- # settings.py
229
- INSTALLED_PACKAGES += [
230
- "plainrequestlog",
231
- ]
232
-
233
- MIDDLEWARE = MIDDLEWARE + [
234
- # ...
235
- "plainrequestlog.RequestLogMiddleware",
236
- ]
237
- ```
238
-
239
- The default settings can be customized if needed:
240
-
241
- ```python
242
- # settings.py
243
- DEV_REQUESTS_IGNORE_PATHS = [
244
- "/sw.js",
245
- "/favicon.ico",
246
- "/admin/jsi18n/",
247
- ]
248
- DEV_REQUESTS_MAX = 50
249
- ```
250
-
251
- ## Tailwind CSS
252
-
253
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
254
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
255
-
256
- If you are using your own Tailwind implementation,
257
- you can modify the "content" in your Tailwind config to include any Plain packages:
258
-
259
- ```js
260
- // tailwind.config.js
261
- module.exports = {
262
- content: [
263
- // ...
264
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
265
- ],
266
- // ...
267
- }
268
- ```
269
-
270
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
271
-
272
- # plain.impersonate
273
-
274
- See what your users see.
275
-
276
- A key feature for providing customer support is to be able to view the site through their account.
277
- With `impersonate` installed, you can impersonate a user by finding them in the Django admin and clicking the "Impersonate" button.
278
-
279
- ![](/docs/img/impersonate-admin.png)
280
-
281
- Then with the [admin toolbar](/docs/plain-toolbar/) enabled, you'll get a notice of the impersonation and a button to exit:
282
-
283
- ![](/docs/img/impersonate-bar.png)
284
-
285
- ## Installation
286
-
287
- To impersonate users, you need the app, middleware, and URLs:
288
-
289
- ```python
290
- # settings.py
291
- INSTALLED_PACKAGES = INSTALLED_PACKAGES + [
292
- "plain.admin.impersonate",
293
- ]
294
-
295
- MIDDLEWARE = MIDDLEWARE + [
296
- "plain.admin.impersonate.ImpersonateMiddleware",
297
- ]
298
- ```
299
-
300
- ```python
301
- # urls.py
302
- urlpatterns = [
303
- # ...
304
- path("impersonate/", include("plain.admin.impersonate.urls")),
305
- ]
306
- ```
307
-
308
- ## Settings
309
-
310
- By default, all admin users can impersonate other users.
311
-
312
- ````python
313
- # settings.py
314
- IMPERSONATE_ALLOWED = lambda user: user.is_admin
315
- ``` -->
316
- ````
@@ -1,301 +0,0 @@
1
- # Admin
2
-
3
- An admin interface for admin users.
4
-
5
- The Plain Admin is a new package built from the ground up.
6
- It leverages class-based views and standard URLs and templates to provide a flexible admin where
7
- you can quickly create your own pages and cards,
8
- in addition to models.
9
-
10
- - cards
11
- - dashboards
12
- - diy forms - have to install elements if you want to use them (or an app uses them, or maybe plain pkgs should use them just for admin...)
13
- - detached from login (do your own login (oauth, passkeys, etc))
14
-
15
- ## Installation
16
-
17
- - install plain.admin and plain.htmx, add plain.admin.admin and plain.htmx to installed packages
18
-
19
- Add the `AdminRouter` to your `urls.py`.
20
-
21
- ```python
22
- # app/urls.py
23
- from plain.admin.urls import AdminRouter
24
- from plain.urls import Router, include, path
25
-
26
- from . import views
27
-
28
-
29
- class AppRouter(Router):
30
- namespace = ""
31
- urls = [
32
- include("admin/", AdminRouter),
33
- path("login/", views.LoginView, name="login"),
34
- path("logout/", LogoutView, name="logout"),
35
- # Your other urls here...
36
- ]
37
-
38
- ```
39
-
40
- Optionally, add the admin toolbar to your base template.
41
-
42
- ```html
43
- <!-- app/templates/base.html -->
44
- <!DOCTYPE html>
45
- <html lang="en">
46
- <head>
47
- <meta charset="UTF-8">
48
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
49
- <title>{{ html_title|default("My App") }}</title>
50
- {% tailwind_css %}
51
- </head>
52
- <body>
53
- {% block content required %}{% endblock %}
54
-
55
- {% toolbar %}
56
- </body>
57
- </html>
58
- ```
59
-
60
- ## Models in the admin
61
-
62
- ## Dashboards
63
-
64
- <!-- # plain.querystats
65
-
66
- On-page database query stats in development and production.
67
-
68
- On each page, the query stats will display how many database queries were performed and how long they took.
69
-
70
- [Watch on YouTube](https://www.youtube.com/watch?v=NX8VXxVJm08)
71
-
72
- Clicking the stats in the toolbar will show the full SQL query log with tracebacks and timings.
73
- This is even designed to work in production,
74
- making it much easier to discover and debug performance issues on production data!
75
-
76
- ![Django query stats](https://user-images.githubusercontent.com/649496/213781593-54197bb6-36a8-4c9d-8294-5b43bd86a4c9.png)
77
-
78
- It will also point out duplicate queries,
79
- which can typically be removed by using `select_related`,
80
- `prefetch_related`, or otherwise refactoring your code.
81
-
82
- ## Installation
83
-
84
- ```python
85
- # settings.py
86
- INSTALLED_PACKAGES = [
87
- # ...
88
- "plain.admin.querystats",
89
- ]
90
-
91
- MIDDLEWARE = [
92
- "plain.sessions.middleware.SessionMiddleware",
93
- "plain.auth.middleware.AuthenticationMiddleware",
94
-
95
- "plain.admin.querystats.QueryStatsMiddleware",
96
- # Put additional middleware below querystats
97
- # ...
98
- ]
99
- ```
100
-
101
- We strongly recommend using the plain-toolbar along with this,
102
- but if you aren't,
103
- you can add the querystats to your frontend templates with this include:
104
-
105
- ```html
106
- {% include "querystats/button.html" %}
107
- ```
108
-
109
- *Note that you will likely want to surround this with an if `DEBUG` or `is_admin` check.*
110
-
111
- To view querystats you need to send a POST request to `?querystats=store` (i.e. via a `<form>`),
112
- and the template include is the easiest way to do that.
113
-
114
- ## Tailwind CSS
115
-
116
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
117
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
118
-
119
- If you are using your own Tailwind implementation,
120
- you can modify the "content" in your Tailwind config to include any Plain packages:
121
-
122
- ```js
123
- // tailwind.config.js
124
- module.exports = {
125
- content: [
126
- // ...
127
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
128
- ],
129
- // ...
130
- }
131
- ```
132
-
133
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
134
-
135
-
136
- # plain.toolbar
137
-
138
- The admin toolbar is enabled for every user who `is_admin`.
139
-
140
- ![Plain Admin toolbar](https://user-images.githubusercontent.com/649496/213781915-a2094f54-99b8-4a05-a36e-dee107405229.png)
141
-
142
- ## Installation
143
-
144
- Add `plaintoolbar` to your `INSTALLED_PACKAGES`,
145
- and the `{% toolbar %}` to your base template:
146
-
147
- ```python
148
- # settings.py
149
- INSTALLED_PACKAGES += [
150
- "plaintoolbar",
151
- ]
152
- ```
153
-
154
- ```html
155
- <!-- base.template.html -->
156
-
157
- {% load toolbar %}
158
-
159
- <!doctype html>
160
- <html lang="en">
161
- <head>
162
- ...
163
- </head>
164
- <body>
165
- {% toolbar %}
166
- ...
167
- </body>
168
- ```
169
-
170
- More specific settings can be found below.
171
-
172
- ## Tailwind CSS
173
-
174
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
175
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
176
-
177
- If you are using your own Tailwind implementation,
178
- you can modify the "content" in your Tailwind config to include any Plain packages:
179
-
180
- ```js
181
- // tailwind.config.js
182
- module.exports = {
183
- content: [
184
- // ...
185
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
186
- ],
187
- // ...
188
- }
189
- ```
190
-
191
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
192
-
193
- # plain.requestlog
194
-
195
- The request log stores a local history of HTTP requests and responses during `plain work` (Django runserver).
196
-
197
- The request history will make it easy to see redirects,
198
- 400 and 500 level errors,
199
- form submissions,
200
- API calls,
201
- webhooks,
202
- and more.
203
-
204
- [Watch on YouTube](https://www.youtube.com/watch?v=AwI7Pt5oZnM)
205
-
206
- Requests can be re-submitted by clicking the "replay" button.
207
-
208
- [![Django request log](https://user-images.githubusercontent.com/649496/213781414-417ad043-de67-4836-9ef1-2b91404336c3.png)](https://user-images.githubusercontent.com/649496/213781414-417ad043-de67-4836-9ef1-2b91404336c3.png)
209
-
210
- ## Installation
211
-
212
- ```python
213
- # settings.py
214
- INSTALLED_PACKAGES += [
215
- "plainrequestlog",
216
- ]
217
-
218
- MIDDLEWARE = MIDDLEWARE + [
219
- # ...
220
- "plainrequestlog.RequestLogMiddleware",
221
- ]
222
- ```
223
-
224
- The default settings can be customized if needed:
225
-
226
- ```python
227
- # settings.py
228
- DEV_REQUESTS_IGNORE_PATHS = [
229
- "/sw.js",
230
- "/favicon.ico",
231
- "/admin/jsi18n/",
232
- ]
233
- DEV_REQUESTS_MAX = 50
234
- ```
235
-
236
- ## Tailwind CSS
237
-
238
- This package is styled with [Tailwind CSS](https://tailwindcss.com/),
239
- and pairs well with [`plain-tailwind`](https://github.com/plainpackages/plain-tailwind).
240
-
241
- If you are using your own Tailwind implementation,
242
- you can modify the "content" in your Tailwind config to include any Plain packages:
243
-
244
- ```js
245
- // tailwind.config.js
246
- module.exports = {
247
- content: [
248
- // ...
249
- ".venv/lib/python*/site-packages/plain*/**/*.{html,js}",
250
- ],
251
- // ...
252
- }
253
- ```
254
-
255
- If you aren't using Tailwind, and don't intend to, open an issue to discuss other options.
256
-
257
- # plain.impersonate
258
-
259
- See what your users see.
260
-
261
- A key feature for providing customer support is to be able to view the site through their account.
262
- With `impersonate` installed, you can impersonate a user by finding them in the Django admin and clicking the "Impersonate" button.
263
-
264
- ![](/docs/img/impersonate-admin.png)
265
-
266
- Then with the [admin toolbar](/docs/plain-toolbar/) enabled, you'll get a notice of the impersonation and a button to exit:
267
-
268
- ![](/docs/img/impersonate-bar.png)
269
-
270
- ## Installation
271
-
272
- To impersonate users, you need the app, middleware, and URLs:
273
-
274
- ```python
275
- # settings.py
276
- INSTALLED_PACKAGES = INSTALLED_PACKAGES + [
277
- "plain.admin.impersonate",
278
- ]
279
-
280
- MIDDLEWARE = MIDDLEWARE + [
281
- "plain.admin.impersonate.ImpersonateMiddleware",
282
- ]
283
- ```
284
-
285
- ```python
286
- # urls.py
287
- urlpatterns = [
288
- # ...
289
- path("impersonate/", include("plain.admin.impersonate.urls")),
290
- ]
291
- ```
292
-
293
- ## Settings
294
-
295
- By default, all admin users can impersonate other users.
296
-
297
- ````python
298
- # settings.py
299
- IMPERSONATE_ALLOWED = lambda user: user.is_admin
300
- ``` -->
301
- ````
File without changes
File without changes