plain 0.58.0__tar.gz → 0.60.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.
- {plain-0.58.0 → plain-0.60.0}/PKG-INFO +1 -1
- {plain-0.58.0 → plain-0.60.0}/plain/CHANGELOG.md +24 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/upgrade.py +1 -0
- {plain-0.58.0 → plain-0.60.0}/plain/runtime/global_settings.py +6 -0
- plain-0.60.0/plain/runtime/utils.py +23 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/objects.py +39 -66
- {plain-0.58.0 → plain-0.60.0}/plain/views/templates.py +6 -0
- {plain-0.58.0 → plain-0.60.0}/pyproject.toml +1 -1
- {plain-0.58.0 → plain-0.60.0}/.gitignore +0 -0
- {plain-0.58.0 → plain-0.60.0}/LICENSE +0 -0
- {plain-0.58.0 → plain-0.60.0}/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/__main__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/compile.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/finders.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/fingerprints.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/urls.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/assets/views.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/chores/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/chores/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/chores/registry.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/agent.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/build.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/changelog.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/chores.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/core.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/docs.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/formatting.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/help.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/install.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/output.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/preflight.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/print.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/registry.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/scaffold.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/settings.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/shell.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/startup.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/urls.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/cli/utils.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/csrf/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/csrf/middleware.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/csrf/views.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/debug.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/exceptions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/boundfield.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/exceptions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/fields.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/forms/forms.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/cookie.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/multipartparser.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/request.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/http/response.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/base.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/locks.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/move.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/temp.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/uploadedfile.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/uploadhandler.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/files/utils.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/handlers/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/handlers/base.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/handlers/exception.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/handlers/wsgi.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/middleware/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/middleware/headers.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/middleware/https.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/internal/middleware/slash.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/json.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/logs/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/logs/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/logs/configure.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/logs/loggers.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/logs/utils.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/packages/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/packages/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/packages/config.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/packages/registry.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/paginator.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/files.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/messages.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/registry.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/security.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/preflight/urls.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/runtime/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/runtime/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/runtime/user_settings.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signals/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signals/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signals/dispatch/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signals/dispatch/dispatcher.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signals/dispatch/license.txt +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/signing.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/core.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/jinja/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/jinja/environments.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/jinja/extensions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/jinja/filters.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/templates/jinja/globals.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/test/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/test/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/test/client.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/test/encoding.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/test/exceptions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/converters.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/exceptions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/patterns.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/resolvers.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/routers.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/urls/utils.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/cache.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/crypto.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/datastructures.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/dateparse.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/deconstruct.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/decorators.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/duration.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/encoding.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/functional.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/hashable.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/html.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/http.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/inspect.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/ipv6.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/itercompat.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/module_loading.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/regex_helper.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/safestring.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/text.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/timesince.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/timezone.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/utils/tree.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/validators.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/README.md +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/base.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/errors.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/exceptions.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/forms.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/views/redirect.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/plain/wsgi.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/.gitignore +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/app/.gitignore +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/app/settings.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/app/test/__init__.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/app/test/default_settings.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/app/urls.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/conftest.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/test_cli.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/test_csrf.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/test_runtime.py +0 -0
- {plain-0.58.0 → plain-0.60.0}/tests/test_wsgi.py +0 -0
@@ -1,5 +1,29 @@
|
|
1
1
|
# plain changelog
|
2
2
|
|
3
|
+
## [0.60.0](https://github.com/dropseed/plain/releases/plain@0.60.0) (2025-08-27)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Added new `APP_VERSION` setting that defaults to the project version from `pyproject.toml` ([57fb948d46](https://github.com/dropseed/plain/commit/57fb948d46))
|
8
|
+
- Updated `get_app_name_from_pyproject()` to `get_app_info_from_pyproject()` to return both name and version ([57fb948d46](https://github.com/dropseed/plain/commit/57fb948d46))
|
9
|
+
|
10
|
+
### Upgrade instructions
|
11
|
+
|
12
|
+
- No changes required
|
13
|
+
|
14
|
+
## [0.59.0](https://github.com/dropseed/plain/releases/plain@0.59.0) (2025-08-22)
|
15
|
+
|
16
|
+
### What's changed
|
17
|
+
|
18
|
+
- Added new `APP_NAME` setting that defaults to the project name from `pyproject.toml` ([1a4d60e](https://github.com/dropseed/plain/commit/1a4d60e787))
|
19
|
+
- Template views now validate that `get_template_names()` returns a list instead of a string ([428a64f](https://github.com/dropseed/plain/commit/428a64f8cc))
|
20
|
+
- Object views now use cached properties for `.object` and `.objects` to improve performance ([bd0507a](https://github.com/dropseed/plain/commit/bd0507a72c))
|
21
|
+
- Improved `plain upgrade` command to suggest using subagents when there are more than 3 package updates ([497c30d](https://github.com/dropseed/plain/commit/497c30d445))
|
22
|
+
|
23
|
+
### Upgrade instructions
|
24
|
+
|
25
|
+
- In object views, `self.load_object()` is no longer necessary as `self.object` is now a cached property.
|
26
|
+
|
3
27
|
## [0.58.0](https://github.com/dropseed/plain/releases/plain@0.58.0) (2025-08-19)
|
4
28
|
|
5
29
|
### What's changed
|
@@ -158,6 +158,7 @@ def build_prompt(before_after: dict[str, tuple[str | None, str | None]]) -> str:
|
|
158
158
|
"",
|
159
159
|
"3. **Available tools:**",
|
160
160
|
" - Python shell: `uv run python`",
|
161
|
+
" - If you have a subagents feature and there are more than three packages here, use subagents",
|
161
162
|
"",
|
162
163
|
"4. **Workflow:**",
|
163
164
|
" - Review changelog for each package → Apply changes → Move to next package",
|
@@ -3,10 +3,16 @@ Default Plain settings. Override these with settings in the module pointed to
|
|
3
3
|
by the PLAIN_SETTINGS_MODULE environment variable.
|
4
4
|
"""
|
5
5
|
|
6
|
+
from .utils import get_app_info_from_pyproject
|
7
|
+
|
6
8
|
# MARK: Core Settings
|
7
9
|
|
8
10
|
DEBUG: bool = False
|
9
11
|
|
12
|
+
name, version = get_app_info_from_pyproject()
|
13
|
+
APP_NAME: str = name
|
14
|
+
APP_VERSION: str = version
|
15
|
+
|
10
16
|
# List of strings representing installed packages.
|
11
17
|
INSTALLED_PACKAGES: list[str] = []
|
12
18
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import tomllib
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
def get_app_info_from_pyproject():
|
6
|
+
"""Get the project name and version from the nearest pyproject.toml file."""
|
7
|
+
current_path = Path.cwd()
|
8
|
+
|
9
|
+
# Walk up the directory tree looking for pyproject.toml
|
10
|
+
for path in [current_path] + list(current_path.parents):
|
11
|
+
pyproject_path = path / "pyproject.toml"
|
12
|
+
if pyproject_path.exists():
|
13
|
+
try:
|
14
|
+
with pyproject_path.open("rb") as f:
|
15
|
+
pyproject = tomllib.load(f)
|
16
|
+
project = pyproject.get("project", {})
|
17
|
+
name = project.get("name", "App")
|
18
|
+
version = project.get("version", "dev")
|
19
|
+
return name, version
|
20
|
+
except (tomllib.TOMLDecodeError, OSError):
|
21
|
+
continue
|
22
|
+
|
23
|
+
return "App", "dev"
|
@@ -1,28 +1,55 @@
|
|
1
|
+
from functools import cached_property
|
2
|
+
|
1
3
|
from plain.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
2
4
|
from plain.forms import Form
|
3
|
-
from plain.http import Http404
|
5
|
+
from plain.http import Http404
|
4
6
|
|
5
7
|
from .forms import FormView
|
6
8
|
from .templates import TemplateView
|
7
9
|
|
8
10
|
|
11
|
+
class CreateView(FormView):
|
12
|
+
"""
|
13
|
+
View for creating a new object, with a response rendered by a template.
|
14
|
+
"""
|
15
|
+
|
16
|
+
# TODO? would rather you have to specify this...
|
17
|
+
def get_success_url(self, form):
|
18
|
+
"""Return the URL to redirect to after processing a valid form."""
|
19
|
+
if self.success_url:
|
20
|
+
url = self.success_url.format(**self.object.__dict__)
|
21
|
+
else:
|
22
|
+
try:
|
23
|
+
url = self.object.get_absolute_url()
|
24
|
+
except AttributeError:
|
25
|
+
raise ImproperlyConfigured(
|
26
|
+
"No URL to redirect to. Either provide a url or define"
|
27
|
+
" a get_absolute_url method on the Model."
|
28
|
+
)
|
29
|
+
return url
|
30
|
+
|
31
|
+
def form_valid(self, form):
|
32
|
+
"""If the form is valid, save the associated model."""
|
33
|
+
self.object = form.save()
|
34
|
+
return super().form_valid(form)
|
35
|
+
|
36
|
+
|
9
37
|
class ObjectTemplateViewMixin:
|
10
38
|
context_object_name = ""
|
11
39
|
|
12
|
-
|
13
|
-
|
14
|
-
return self.render_template()
|
15
|
-
|
16
|
-
def load_object(self) -> None:
|
40
|
+
@cached_property
|
41
|
+
def object(self):
|
17
42
|
try:
|
18
|
-
|
43
|
+
obj = self.get_object()
|
19
44
|
except ObjectDoesNotExist:
|
20
45
|
raise Http404
|
21
46
|
|
22
|
-
if not
|
47
|
+
if not obj:
|
23
48
|
# Also raise 404 if the object is None
|
24
49
|
raise Http404
|
25
50
|
|
51
|
+
return obj
|
52
|
+
|
26
53
|
def get_object(self): # Intentionally untyped... subclasses must override this.
|
27
54
|
raise NotImplementedError(
|
28
55
|
f"get_object() is not implemented on {self.__class__.__name__}"
|
@@ -50,55 +77,9 @@ class DetailView(ObjectTemplateViewMixin, TemplateView):
|
|
50
77
|
pass
|
51
78
|
|
52
79
|
|
53
|
-
class CreateView(ObjectTemplateViewMixin, FormView):
|
54
|
-
"""
|
55
|
-
View for creating a new object, with a response rendered by a template.
|
56
|
-
"""
|
57
|
-
|
58
|
-
def post(self) -> Response:
|
59
|
-
"""
|
60
|
-
Handle POST requests: instantiate a form instance with the passed
|
61
|
-
POST variables and then check if it's valid.
|
62
|
-
"""
|
63
|
-
# Context expects self.object to exist
|
64
|
-
self.load_object()
|
65
|
-
return super().post()
|
66
|
-
|
67
|
-
def load_object(self) -> None:
|
68
|
-
self.object = None
|
69
|
-
|
70
|
-
# TODO? would rather you have to specify this...
|
71
|
-
def get_success_url(self, form):
|
72
|
-
"""Return the URL to redirect to after processing a valid form."""
|
73
|
-
if self.success_url:
|
74
|
-
url = self.success_url.format(**self.object.__dict__)
|
75
|
-
else:
|
76
|
-
try:
|
77
|
-
url = self.object.get_absolute_url()
|
78
|
-
except AttributeError:
|
79
|
-
raise ImproperlyConfigured(
|
80
|
-
"No URL to redirect to. Either provide a url or define"
|
81
|
-
" a get_absolute_url method on the Model."
|
82
|
-
)
|
83
|
-
return url
|
84
|
-
|
85
|
-
def form_valid(self, form):
|
86
|
-
"""If the form is valid, save the associated model."""
|
87
|
-
self.object = form.save()
|
88
|
-
return super().form_valid(form)
|
89
|
-
|
90
|
-
|
91
80
|
class UpdateView(ObjectTemplateViewMixin, FormView):
|
92
81
|
"""View for updating an object, with a response rendered by a template."""
|
93
82
|
|
94
|
-
def post(self) -> Response:
|
95
|
-
"""
|
96
|
-
Handle POST requests: instantiate a form instance with the passed
|
97
|
-
POST variables and then check if it's valid.
|
98
|
-
"""
|
99
|
-
self.load_object()
|
100
|
-
return super().post()
|
101
|
-
|
102
83
|
def get_success_url(self, form):
|
103
84
|
"""Return the URL to redirect to after processing a valid form."""
|
104
85
|
if self.success_url:
|
@@ -115,7 +96,7 @@ class UpdateView(ObjectTemplateViewMixin, FormView):
|
|
115
96
|
|
116
97
|
def form_valid(self, form):
|
117
98
|
"""If the form is valid, save the associated model."""
|
118
|
-
|
99
|
+
form.save()
|
119
100
|
return super().form_valid(form)
|
120
101
|
|
121
102
|
def get_form_kwargs(self):
|
@@ -141,14 +122,6 @@ class DeleteView(ObjectTemplateViewMixin, FormView):
|
|
141
122
|
|
142
123
|
form_class = EmptyDeleteForm
|
143
124
|
|
144
|
-
def post(self) -> Response:
|
145
|
-
"""
|
146
|
-
Handle POST requests: instantiate a form instance with the passed
|
147
|
-
POST variables and then check if it's valid.
|
148
|
-
"""
|
149
|
-
self.load_object()
|
150
|
-
return super().post()
|
151
|
-
|
152
125
|
def get_form_kwargs(self):
|
153
126
|
"""Return the keyword arguments for instantiating the form."""
|
154
127
|
kwargs = super().get_form_kwargs()
|
@@ -169,9 +142,9 @@ class ListView(TemplateView):
|
|
169
142
|
|
170
143
|
context_object_name = ""
|
171
144
|
|
172
|
-
|
173
|
-
|
174
|
-
return
|
145
|
+
@cached_property
|
146
|
+
def objects(self):
|
147
|
+
return self.get_objects()
|
175
148
|
|
176
149
|
def get_objects(self):
|
177
150
|
raise NotImplementedError(
|
@@ -36,6 +36,12 @@ class TemplateView(View):
|
|
36
36
|
def get_template(self) -> Template:
|
37
37
|
template_names = self.get_template_names()
|
38
38
|
|
39
|
+
if isinstance(template_names, str):
|
40
|
+
raise ImproperlyConfigured(
|
41
|
+
f"{self.__class__.__name__}.get_template_names() must return a list of strings, "
|
42
|
+
f"not a string. Did you mean to return ['{template_names}']?"
|
43
|
+
)
|
44
|
+
|
39
45
|
if not template_names:
|
40
46
|
raise ImproperlyConfigured(
|
41
47
|
f"{self.__class__.__name__} requires a template_name or get_template_names()."
|
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
|
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
|