plain 0.20.0__tar.gz → 0.21.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 (157) hide show
  1. {plain-0.20.0 → plain-0.21.1}/PKG-INFO +1 -1
  2. {plain-0.20.0 → plain-0.21.1}/plain/internal/handlers/base.py +12 -5
  3. {plain-0.20.0 → plain-0.21.1}/plain/views/objects.py +26 -12
  4. {plain-0.20.0 → plain-0.21.1}/pyproject.toml +1 -1
  5. {plain-0.20.0 → plain-0.21.1}/.gitignore +0 -0
  6. {plain-0.20.0 → plain-0.21.1}/LICENSE +0 -0
  7. {plain-0.20.0 → plain-0.21.1}/README.md +0 -0
  8. {plain-0.20.0 → plain-0.21.1}/plain/README.md +0 -0
  9. {plain-0.20.0 → plain-0.21.1}/plain/__main__.py +0 -0
  10. {plain-0.20.0 → plain-0.21.1}/plain/assets/README.md +0 -0
  11. {plain-0.20.0 → plain-0.21.1}/plain/assets/__init__.py +0 -0
  12. {plain-0.20.0 → plain-0.21.1}/plain/assets/compile.py +0 -0
  13. {plain-0.20.0 → plain-0.21.1}/plain/assets/finders.py +0 -0
  14. {plain-0.20.0 → plain-0.21.1}/plain/assets/fingerprints.py +0 -0
  15. {plain-0.20.0 → plain-0.21.1}/plain/assets/urls.py +0 -0
  16. {plain-0.20.0 → plain-0.21.1}/plain/assets/views.py +0 -0
  17. {plain-0.20.0 → plain-0.21.1}/plain/cli/README.md +0 -0
  18. {plain-0.20.0 → plain-0.21.1}/plain/cli/__init__.py +0 -0
  19. {plain-0.20.0 → plain-0.21.1}/plain/cli/cli.py +0 -0
  20. {plain-0.20.0 → plain-0.21.1}/plain/cli/formatting.py +0 -0
  21. {plain-0.20.0 → plain-0.21.1}/plain/cli/packages.py +0 -0
  22. {plain-0.20.0 → plain-0.21.1}/plain/cli/print.py +0 -0
  23. {plain-0.20.0 → plain-0.21.1}/plain/cli/startup.py +0 -0
  24. {plain-0.20.0 → plain-0.21.1}/plain/csrf/README.md +0 -0
  25. {plain-0.20.0 → plain-0.21.1}/plain/csrf/middleware.py +0 -0
  26. {plain-0.20.0 → plain-0.21.1}/plain/csrf/views.py +0 -0
  27. {plain-0.20.0 → plain-0.21.1}/plain/debug.py +0 -0
  28. {plain-0.20.0 → plain-0.21.1}/plain/exceptions.py +0 -0
  29. {plain-0.20.0 → plain-0.21.1}/plain/forms/README.md +0 -0
  30. {plain-0.20.0 → plain-0.21.1}/plain/forms/__init__.py +0 -0
  31. {plain-0.20.0 → plain-0.21.1}/plain/forms/boundfield.py +0 -0
  32. {plain-0.20.0 → plain-0.21.1}/plain/forms/exceptions.py +0 -0
  33. {plain-0.20.0 → plain-0.21.1}/plain/forms/fields.py +0 -0
  34. {plain-0.20.0 → plain-0.21.1}/plain/forms/forms.py +0 -0
  35. {plain-0.20.0 → plain-0.21.1}/plain/http/README.md +0 -0
  36. {plain-0.20.0 → plain-0.21.1}/plain/http/__init__.py +0 -0
  37. {plain-0.20.0 → plain-0.21.1}/plain/http/cookie.py +0 -0
  38. {plain-0.20.0 → plain-0.21.1}/plain/http/multipartparser.py +0 -0
  39. {plain-0.20.0 → plain-0.21.1}/plain/http/request.py +0 -0
  40. {plain-0.20.0 → plain-0.21.1}/plain/http/response.py +0 -0
  41. {plain-0.20.0 → plain-0.21.1}/plain/internal/__init__.py +0 -0
  42. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/README.md +0 -0
  43. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/__init__.py +0 -0
  44. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/base.py +0 -0
  45. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/locks.py +0 -0
  46. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/move.py +0 -0
  47. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/temp.py +0 -0
  48. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/uploadedfile.py +0 -0
  49. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/uploadhandler.py +0 -0
  50. {plain-0.20.0 → plain-0.21.1}/plain/internal/files/utils.py +0 -0
  51. {plain-0.20.0 → plain-0.21.1}/plain/internal/handlers/__init__.py +0 -0
  52. {plain-0.20.0 → plain-0.21.1}/plain/internal/handlers/exception.py +0 -0
  53. {plain-0.20.0 → plain-0.21.1}/plain/internal/handlers/wsgi.py +0 -0
  54. {plain-0.20.0 → plain-0.21.1}/plain/internal/middleware/__init__.py +0 -0
  55. {plain-0.20.0 → plain-0.21.1}/plain/internal/middleware/headers.py +0 -0
  56. {plain-0.20.0 → plain-0.21.1}/plain/internal/middleware/https.py +0 -0
  57. {plain-0.20.0 → plain-0.21.1}/plain/internal/middleware/slash.py +0 -0
  58. {plain-0.20.0 → plain-0.21.1}/plain/json.py +0 -0
  59. {plain-0.20.0 → plain-0.21.1}/plain/logs/README.md +0 -0
  60. {plain-0.20.0 → plain-0.21.1}/plain/logs/__init__.py +0 -0
  61. {plain-0.20.0 → plain-0.21.1}/plain/logs/configure.py +0 -0
  62. {plain-0.20.0 → plain-0.21.1}/plain/logs/loggers.py +0 -0
  63. {plain-0.20.0 → plain-0.21.1}/plain/logs/utils.py +0 -0
  64. {plain-0.20.0 → plain-0.21.1}/plain/packages/README.md +0 -0
  65. {plain-0.20.0 → plain-0.21.1}/plain/packages/__init__.py +0 -0
  66. {plain-0.20.0 → plain-0.21.1}/plain/packages/config.py +0 -0
  67. {plain-0.20.0 → plain-0.21.1}/plain/packages/registry.py +0 -0
  68. {plain-0.20.0 → plain-0.21.1}/plain/paginator.py +0 -0
  69. {plain-0.20.0 → plain-0.21.1}/plain/preflight/README.md +0 -0
  70. {plain-0.20.0 → plain-0.21.1}/plain/preflight/__init__.py +0 -0
  71. {plain-0.20.0 → plain-0.21.1}/plain/preflight/files.py +0 -0
  72. {plain-0.20.0 → plain-0.21.1}/plain/preflight/messages.py +0 -0
  73. {plain-0.20.0 → plain-0.21.1}/plain/preflight/registry.py +0 -0
  74. {plain-0.20.0 → plain-0.21.1}/plain/preflight/security.py +0 -0
  75. {plain-0.20.0 → plain-0.21.1}/plain/preflight/urls.py +0 -0
  76. {plain-0.20.0 → plain-0.21.1}/plain/runtime/README.md +0 -0
  77. {plain-0.20.0 → plain-0.21.1}/plain/runtime/__init__.py +0 -0
  78. {plain-0.20.0 → plain-0.21.1}/plain/runtime/global_settings.py +0 -0
  79. {plain-0.20.0 → plain-0.21.1}/plain/runtime/user_settings.py +0 -0
  80. {plain-0.20.0 → plain-0.21.1}/plain/signals/README.md +0 -0
  81. {plain-0.20.0 → plain-0.21.1}/plain/signals/__init__.py +0 -0
  82. {plain-0.20.0 → plain-0.21.1}/plain/signals/dispatch/__init__.py +0 -0
  83. {plain-0.20.0 → plain-0.21.1}/plain/signals/dispatch/dispatcher.py +0 -0
  84. {plain-0.20.0 → plain-0.21.1}/plain/signals/dispatch/license.txt +0 -0
  85. {plain-0.20.0 → plain-0.21.1}/plain/signing.py +0 -0
  86. {plain-0.20.0 → plain-0.21.1}/plain/templates/README.md +0 -0
  87. {plain-0.20.0 → plain-0.21.1}/plain/templates/__init__.py +0 -0
  88. {plain-0.20.0 → plain-0.21.1}/plain/templates/core.py +0 -0
  89. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/README.md +0 -0
  90. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/__init__.py +0 -0
  91. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/environments.py +0 -0
  92. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/extensions.py +0 -0
  93. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/filters.py +0 -0
  94. {plain-0.20.0 → plain-0.21.1}/plain/templates/jinja/globals.py +0 -0
  95. {plain-0.20.0 → plain-0.21.1}/plain/test/README.md +0 -0
  96. {plain-0.20.0 → plain-0.21.1}/plain/test/__init__.py +0 -0
  97. {plain-0.20.0 → plain-0.21.1}/plain/test/client.py +0 -0
  98. {plain-0.20.0 → plain-0.21.1}/plain/urls/README.md +0 -0
  99. {plain-0.20.0 → plain-0.21.1}/plain/urls/__init__.py +0 -0
  100. {plain-0.20.0 → plain-0.21.1}/plain/urls/base.py +0 -0
  101. {plain-0.20.0 → plain-0.21.1}/plain/urls/conf.py +0 -0
  102. {plain-0.20.0 → plain-0.21.1}/plain/urls/converters.py +0 -0
  103. {plain-0.20.0 → plain-0.21.1}/plain/urls/exceptions.py +0 -0
  104. {plain-0.20.0 → plain-0.21.1}/plain/urls/resolvers.py +0 -0
  105. {plain-0.20.0 → plain-0.21.1}/plain/utils/README.md +0 -0
  106. {plain-0.20.0 → plain-0.21.1}/plain/utils/__init__.py +0 -0
  107. {plain-0.20.0 → plain-0.21.1}/plain/utils/_os.py +0 -0
  108. {plain-0.20.0 → plain-0.21.1}/plain/utils/cache.py +0 -0
  109. {plain-0.20.0 → plain-0.21.1}/plain/utils/connection.py +0 -0
  110. {plain-0.20.0 → plain-0.21.1}/plain/utils/crypto.py +0 -0
  111. {plain-0.20.0 → plain-0.21.1}/plain/utils/datastructures.py +0 -0
  112. {plain-0.20.0 → plain-0.21.1}/plain/utils/dateformat.py +0 -0
  113. {plain-0.20.0 → plain-0.21.1}/plain/utils/dateparse.py +0 -0
  114. {plain-0.20.0 → plain-0.21.1}/plain/utils/dates.py +0 -0
  115. {plain-0.20.0 → plain-0.21.1}/plain/utils/deconstruct.py +0 -0
  116. {plain-0.20.0 → plain-0.21.1}/plain/utils/decorators.py +0 -0
  117. {plain-0.20.0 → plain-0.21.1}/plain/utils/deprecation.py +0 -0
  118. {plain-0.20.0 → plain-0.21.1}/plain/utils/duration.py +0 -0
  119. {plain-0.20.0 → plain-0.21.1}/plain/utils/email.py +0 -0
  120. {plain-0.20.0 → plain-0.21.1}/plain/utils/encoding.py +0 -0
  121. {plain-0.20.0 → plain-0.21.1}/plain/utils/functional.py +0 -0
  122. {plain-0.20.0 → plain-0.21.1}/plain/utils/hashable.py +0 -0
  123. {plain-0.20.0 → plain-0.21.1}/plain/utils/html.py +0 -0
  124. {plain-0.20.0 → plain-0.21.1}/plain/utils/http.py +0 -0
  125. {plain-0.20.0 → plain-0.21.1}/plain/utils/inspect.py +0 -0
  126. {plain-0.20.0 → plain-0.21.1}/plain/utils/ipv6.py +0 -0
  127. {plain-0.20.0 → plain-0.21.1}/plain/utils/itercompat.py +0 -0
  128. {plain-0.20.0 → plain-0.21.1}/plain/utils/module_loading.py +0 -0
  129. {plain-0.20.0 → plain-0.21.1}/plain/utils/regex_helper.py +0 -0
  130. {plain-0.20.0 → plain-0.21.1}/plain/utils/safestring.py +0 -0
  131. {plain-0.20.0 → plain-0.21.1}/plain/utils/text.py +0 -0
  132. {plain-0.20.0 → plain-0.21.1}/plain/utils/timesince.py +0 -0
  133. {plain-0.20.0 → plain-0.21.1}/plain/utils/timezone.py +0 -0
  134. {plain-0.20.0 → plain-0.21.1}/plain/utils/tree.py +0 -0
  135. {plain-0.20.0 → plain-0.21.1}/plain/validators.py +0 -0
  136. {plain-0.20.0 → plain-0.21.1}/plain/views/README.md +0 -0
  137. {plain-0.20.0 → plain-0.21.1}/plain/views/__init__.py +0 -0
  138. {plain-0.20.0 → plain-0.21.1}/plain/views/base.py +0 -0
  139. {plain-0.20.0 → plain-0.21.1}/plain/views/csrf.py +0 -0
  140. {plain-0.20.0 → plain-0.21.1}/plain/views/errors.py +0 -0
  141. {plain-0.20.0 → plain-0.21.1}/plain/views/exceptions.py +0 -0
  142. {plain-0.20.0 → plain-0.21.1}/plain/views/forms.py +0 -0
  143. {plain-0.20.0 → plain-0.21.1}/plain/views/redirect.py +0 -0
  144. {plain-0.20.0 → plain-0.21.1}/plain/views/templates.py +0 -0
  145. {plain-0.20.0 → plain-0.21.1}/plain/wsgi.py +0 -0
  146. {plain-0.20.0 → plain-0.21.1}/tests/.bolt/assets_collected/assets.json +0 -0
  147. {plain-0.20.0 → plain-0.21.1}/tests/.gitignore +0 -0
  148. {plain-0.20.0 → plain-0.21.1}/tests/app/.gitignore +0 -0
  149. {plain-0.20.0 → plain-0.21.1}/tests/app/settings.py +0 -0
  150. {plain-0.20.0 → plain-0.21.1}/tests/app/test/__init__.py +0 -0
  151. {plain-0.20.0 → plain-0.21.1}/tests/app/test/default_settings.py +0 -0
  152. {plain-0.20.0 → plain-0.21.1}/tests/app/urls.py +0 -0
  153. {plain-0.20.0 → plain-0.21.1}/tests/conftest.py +0 -0
  154. {plain-0.20.0 → plain-0.21.1}/tests/test_cli.py +0 -0
  155. {plain-0.20.0 → plain-0.21.1}/tests/test_runtime.py +0 -0
  156. {plain-0.20.0 → plain-0.21.1}/tests/test_wsgi.py +0 -0
  157. {plain-0.20.0 → plain-0.21.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.20.0
3
+ Version: 0.21.1
4
4
  Summary: A web framework for building products with Python.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -14,11 +14,16 @@ logger = logging.getLogger("plain.request")
14
14
 
15
15
 
16
16
  # These middleware classes are always used by Plain.
17
- BUILTIN_MIDDLEWARE = [
18
- "plain.internal.middleware.headers.DefaultHeadersMiddleware",
19
- "plain.internal.middleware.https.HttpsRedirectMiddleware",
17
+ BUILTIN_BEFORE_MIDDLEWARE = [
18
+ "plain.internal.middleware.headers.DefaultHeadersMiddleware", # Runs after response, to set missing headers
19
+ "plain.internal.middleware.https.HttpsRedirectMiddleware", # Runs before response, to redirect to HTTPS quickly
20
+ "plain.csrf.middleware.CsrfViewMiddleware", # Runs before and after get_response...
21
+ ]
22
+
23
+ BUILTIN_AFTER_MIDDLEWARE = [
24
+ # Want this to run first (when reversed) so the slash middleware
25
+ # can immediately redirect to the slash-appended path if there is one.
20
26
  "plain.internal.middleware.slash.RedirectSlashMiddleware",
21
- "plain.csrf.middleware.CsrfViewMiddleware",
22
27
  ]
23
28
 
24
29
 
@@ -34,7 +39,9 @@ class BaseHandler:
34
39
  get_response = self._get_response
35
40
  handler = convert_exception_to_response(get_response)
36
41
 
37
- middlewares = reversed(BUILTIN_MIDDLEWARE + settings.MIDDLEWARE)
42
+ middlewares = reversed(
43
+ BUILTIN_BEFORE_MIDDLEWARE + settings.MIDDLEWARE + BUILTIN_AFTER_MIDDLEWARE
44
+ )
38
45
 
39
46
  for middleware_path in middlewares:
40
47
  middleware = import_string(middleware_path)
@@ -1,5 +1,6 @@
1
1
  from plain.exceptions import ImproperlyConfigured, ObjectDoesNotExist
2
- from plain.http import Http404, Response, ResponseRedirect
2
+ from plain.forms import Form
3
+ from plain.http import Http404, Response
3
4
 
4
5
  from .forms import FormView
5
6
  from .templates import TemplateView
@@ -80,6 +81,8 @@ class CreateView(ObjectTemplateViewMixin, FormView):
80
81
  View for creating a new object, with a response rendered by a template.
81
82
  """
82
83
 
84
+ template_name_suffix = "_form"
85
+
83
86
  def post(self) -> Response:
84
87
  """
85
88
  Handle POST requests: instantiate a form instance with the passed
@@ -152,30 +155,41 @@ class UpdateView(ObjectTemplateViewMixin, FormView):
152
155
  return kwargs
153
156
 
154
157
 
155
- class DeleteView(ObjectTemplateViewMixin, TemplateView):
158
+ class DeleteView(ObjectTemplateViewMixin, FormView):
156
159
  """
157
160
  View for deleting an object retrieved with self.get_object(), with a
158
161
  response rendered by a template.
159
162
  """
160
163
 
164
+ class EmptyDeleteForm(Form):
165
+ def __init__(self, instance, *args, **kwargs):
166
+ self.instance = instance
167
+ super().__init__(*args, **kwargs)
168
+
169
+ def save(self):
170
+ self.instance.delete()
171
+
172
+ form_class = EmptyDeleteForm
161
173
  template_name_suffix = "_confirm_delete"
162
174
 
175
+ def post(self) -> Response:
176
+ """
177
+ Handle POST requests: instantiate a form instance with the passed
178
+ POST variables and then check if it's valid.
179
+ """
180
+ self.load_object()
181
+ return super().post()
182
+
163
183
  def get_form_kwargs(self):
164
184
  """Return the keyword arguments for instantiating the form."""
165
185
  kwargs = super().get_form_kwargs()
166
186
  kwargs.update({"instance": self.object})
167
187
  return kwargs
168
188
 
169
- def get_success_url(self):
170
- if self.success_url:
171
- return self.success_url.format(**self.object.__dict__)
172
- else:
173
- raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
174
-
175
- def post(self):
176
- self.load_object()
177
- self.object.delete()
178
- return ResponseRedirect(self.get_success_url())
189
+ def form_valid(self, form):
190
+ """If the form is valid, save the associated model."""
191
+ form.save()
192
+ return super().form_valid(form)
179
193
 
180
194
 
181
195
  class ListView(TemplateView):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain"
3
- version = "0.20.0"
3
+ version = "0.21.1"
4
4
  description = "A web framework for building products with Python."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes