plain 0.56.1__tar.gz → 0.57.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.56.1 → plain-0.57.0}/PKG-INFO +1 -1
- {plain-0.56.1 → plain-0.57.0}/plain/CHANGELOG.md +15 -0
- {plain-0.56.1 → plain-0.57.0}/plain/exceptions.py +0 -6
- {plain-0.56.1 → plain-0.57.0}/plain/http/__init__.py +0 -2
- {plain-0.56.1 → plain-0.57.0}/plain/http/response.py +7 -22
- {plain-0.56.1 → plain-0.57.0}/plain/internal/middleware/https.py +4 -2
- {plain-0.56.1 → plain-0.57.0}/plain/internal/middleware/slash.py +4 -2
- plain-0.57.0/plain/views/redirect.py +66 -0
- {plain-0.56.1 → plain-0.57.0}/pyproject.toml +1 -1
- plain-0.56.1/plain/views/redirect.py +0 -77
- {plain-0.56.1 → plain-0.57.0}/.gitignore +0 -0
- {plain-0.56.1 → plain-0.57.0}/LICENSE +0 -0
- {plain-0.56.1 → plain-0.57.0}/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/__main__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/compile.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/finders.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/fingerprints.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/urls.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/assets/views.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/chores/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/chores/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/chores/registry.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/agent.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/build.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/changelog.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/chores.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/core.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/docs.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/formatting.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/help.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/install.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/output.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/preflight.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/print.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/registry.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/scaffold.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/settings.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/shell.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/startup.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/upgrade.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/urls.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/cli/utils.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/csrf/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/csrf/middleware.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/csrf/views.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/debug.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/boundfield.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/exceptions.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/fields.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/forms/forms.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/http/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/http/cookie.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/http/multipartparser.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/http/request.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/base.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/locks.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/move.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/temp.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/uploadedfile.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/uploadhandler.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/files/utils.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/handlers/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/handlers/base.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/handlers/exception.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/handlers/wsgi.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/middleware/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/internal/middleware/headers.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/json.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/logs/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/logs/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/logs/configure.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/logs/loggers.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/logs/utils.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/packages/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/packages/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/packages/config.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/packages/registry.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/paginator.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/files.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/messages.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/registry.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/security.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/preflight/urls.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/runtime/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/runtime/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/runtime/global_settings.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/runtime/user_settings.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signals/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signals/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signals/dispatch/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signals/dispatch/dispatcher.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signals/dispatch/license.txt +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/signing.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/core.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/jinja/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/jinja/environments.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/jinja/extensions.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/jinja/filters.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/templates/jinja/globals.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/test/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/test/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/test/client.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/test/encoding.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/test/exceptions.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/converters.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/exceptions.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/patterns.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/resolvers.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/routers.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/urls/utils.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/cache.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/crypto.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/datastructures.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/dateparse.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/deconstruct.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/decorators.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/duration.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/encoding.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/functional.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/hashable.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/html.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/http.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/inspect.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/ipv6.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/itercompat.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/module_loading.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/regex_helper.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/safestring.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/text.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/timesince.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/timezone.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/utils/tree.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/validators.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/README.md +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/base.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/csrf.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/errors.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/exceptions.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/forms.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/objects.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/views/templates.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/plain/wsgi.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/.gitignore +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/app/.gitignore +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/app/settings.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/app/test/__init__.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/app/test/default_settings.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/app/urls.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/conftest.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/test_cli.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/test_runtime.py +0 -0
- {plain-0.56.1 → plain-0.57.0}/tests/test_wsgi.py +0 -0
@@ -1,5 +1,20 @@
|
|
1
1
|
# plain changelog
|
2
2
|
|
3
|
+
## [0.57.0](https://github.com/dropseed/plain/releases/plain@0.57.0) (2025-08-15)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- The `ResponsePermanentRedirect` class has been removed; use `ResponseRedirect` with `status_code=301` instead ([d5735ea](https://github.com/dropseed/plain/commit/d5735ea4f8))
|
8
|
+
- The `RedirectView.permanent` attribute has been replaced with `status_code` for more flexible redirect status codes ([12dda16](https://github.com/dropseed/plain/commit/12dda16731))
|
9
|
+
- Updated `RedirectView` initialization parameters: `url_name` replaces `pattern_name`, `preserve_query_params` replaces `query_string`, and removed 410 Gone functionality ([3b9ca71](https://github.com/dropseed/plain/commit/3b9ca713bf))
|
10
|
+
|
11
|
+
### Upgrade instructions
|
12
|
+
|
13
|
+
- Replace `ResponsePermanentRedirect` imports with `ResponseRedirect` and pass `status_code=301` to the constructor
|
14
|
+
- Update `RedirectView` subclasses to use `status_code=301` instead of `permanent=True`
|
15
|
+
- Replace `pattern_name` with `url_name` in RedirectView usage
|
16
|
+
- Replace `query_string=True` with `preserve_query_params=True` in RedirectView usage
|
17
|
+
|
3
18
|
## [0.56.1](https://github.com/dropseed/plain/releases/plain@0.56.1) (2025-07-30)
|
4
19
|
|
5
20
|
### What's changed
|
@@ -53,12 +53,6 @@ class DisallowedHost(SuspiciousOperation):
|
|
53
53
|
pass
|
54
54
|
|
55
55
|
|
56
|
-
class DisallowedRedirect(SuspiciousOperation):
|
57
|
-
"""Redirect to scheme not in allowed list"""
|
58
|
-
|
59
|
-
pass
|
60
|
-
|
61
|
-
|
62
56
|
class TooManyFieldsSent(SuspiciousOperation):
|
63
57
|
"""
|
64
58
|
The number of fields in a GET or POST request exceeded
|
@@ -19,7 +19,6 @@ from plain.http.response import (
|
|
19
19
|
ResponseNotAllowed,
|
20
20
|
ResponseNotFound,
|
21
21
|
ResponseNotModified,
|
22
|
-
ResponsePermanentRedirect,
|
23
22
|
ResponseRedirect,
|
24
23
|
ResponseServerError,
|
25
24
|
StreamingResponse,
|
@@ -36,7 +35,6 @@ __all__ = [
|
|
36
35
|
"ResponseBase",
|
37
36
|
"StreamingResponse",
|
38
37
|
"ResponseRedirect",
|
39
|
-
"ResponsePermanentRedirect",
|
40
38
|
"ResponseNotModified",
|
41
39
|
"ResponseBadRequest",
|
42
40
|
"ResponseForbidden",
|
@@ -10,10 +10,8 @@ from email.header import Header
|
|
10
10
|
from functools import cached_property
|
11
11
|
from http.client import responses
|
12
12
|
from http.cookies import SimpleCookie
|
13
|
-
from urllib.parse import urlparse
|
14
13
|
|
15
14
|
from plain import signals
|
16
|
-
from plain.exceptions import DisallowedRedirect
|
17
15
|
from plain.http.cookie import sign_cookie_value
|
18
16
|
from plain.json import PlainJSONEncoder
|
19
17
|
from plain.runtime import settings
|
@@ -566,19 +564,18 @@ class FileResponse(StreamingResponse):
|
|
566
564
|
self.headers["Content-Disposition"] = content_disposition
|
567
565
|
|
568
566
|
|
569
|
-
class
|
570
|
-
|
567
|
+
class ResponseRedirect(Response):
|
568
|
+
"""HTTP redirect response"""
|
569
|
+
|
570
|
+
status_code = 302
|
571
571
|
|
572
572
|
def __init__(self, redirect_to, **kwargs):
|
573
573
|
super().__init__(**kwargs)
|
574
574
|
self.headers["Location"] = iri_to_uri(redirect_to)
|
575
|
-
parsed = urlparse(str(redirect_to))
|
576
|
-
if parsed.scheme and parsed.scheme not in self.allowed_schemes:
|
577
|
-
raise DisallowedRedirect(
|
578
|
-
f"Unsafe redirect to URL with protocol '{parsed.scheme}'"
|
579
|
-
)
|
580
575
|
|
581
|
-
|
576
|
+
@property
|
577
|
+
def url(self):
|
578
|
+
return self.headers["Location"]
|
582
579
|
|
583
580
|
def __repr__(self):
|
584
581
|
return (
|
@@ -592,18 +589,6 @@ class ResponseRedirectBase(Response):
|
|
592
589
|
)
|
593
590
|
|
594
591
|
|
595
|
-
class ResponseRedirect(ResponseRedirectBase):
|
596
|
-
"""HTTP 302 response"""
|
597
|
-
|
598
|
-
status_code = 302
|
599
|
-
|
600
|
-
|
601
|
-
class ResponsePermanentRedirect(ResponseRedirectBase):
|
602
|
-
"""HTTP 301 response"""
|
603
|
-
|
604
|
-
status_code = 301
|
605
|
-
|
606
|
-
|
607
592
|
class ResponseNotModified(Response):
|
608
593
|
"""HTTP 304 response"""
|
609
594
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import re
|
2
2
|
|
3
|
-
from plain.http import
|
3
|
+
from plain.http import ResponseRedirect
|
4
4
|
from plain.runtime import settings
|
5
5
|
|
6
6
|
|
@@ -33,4 +33,6 @@ class HttpsRedirectMiddleware:
|
|
33
33
|
and not any(pattern.search(path) for pattern in self.https_redirect_exempt)
|
34
34
|
):
|
35
35
|
host = self.https_redirect_host or request.get_host()
|
36
|
-
return
|
36
|
+
return ResponseRedirect(
|
37
|
+
f"https://{host}{request.get_full_path()}", status_code=301
|
38
|
+
)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from plain.http import
|
1
|
+
from plain.http import ResponseRedirect
|
2
2
|
from plain.runtime import settings
|
3
3
|
from plain.urls import Resolver404, get_resolver
|
4
4
|
from plain.utils.http import escape_leading_slashes
|
@@ -22,7 +22,9 @@ class RedirectSlashMiddleware:
|
|
22
22
|
# If the given URL is "Not Found", then check if we should redirect to
|
23
23
|
# a path with a slash appended.
|
24
24
|
if response.status_code == 404 and self.should_redirect_with_slash(request):
|
25
|
-
return
|
25
|
+
return ResponseRedirect(
|
26
|
+
self.get_full_path_with_slash(request), status_code=301
|
27
|
+
)
|
26
28
|
|
27
29
|
return response
|
28
30
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
from plain.http import ResponseRedirect
|
2
|
+
from plain.urls import reverse
|
3
|
+
|
4
|
+
from .base import View
|
5
|
+
|
6
|
+
|
7
|
+
class RedirectView(View):
|
8
|
+
"""Provide a redirect on any GET request."""
|
9
|
+
|
10
|
+
status_code = 302
|
11
|
+
url: str | None = None
|
12
|
+
url_name: str | None = None
|
13
|
+
preserve_query_params = False
|
14
|
+
|
15
|
+
def __init__(
|
16
|
+
self, url=None, status_code=None, url_name=None, preserve_query_params=None
|
17
|
+
):
|
18
|
+
# Allow attributes to be set in RedirectView.as_view(url="...", status_code=301, etc.)
|
19
|
+
self.url = url or self.url
|
20
|
+
self.status_code = status_code if status_code is not None else self.status_code
|
21
|
+
self.url_name = url_name or self.url_name
|
22
|
+
self.preserve_query_params = (
|
23
|
+
preserve_query_params
|
24
|
+
if preserve_query_params is not None
|
25
|
+
else self.preserve_query_params
|
26
|
+
)
|
27
|
+
|
28
|
+
def get_redirect_url(self):
|
29
|
+
"""
|
30
|
+
Return the URL redirect to. Keyword arguments from the URL pattern
|
31
|
+
match generating the redirect request are provided as kwargs to this
|
32
|
+
method.
|
33
|
+
"""
|
34
|
+
if self.url:
|
35
|
+
url = self.url % self.url_kwargs
|
36
|
+
elif self.url_name:
|
37
|
+
url = reverse(self.url_name, *self.url_args, **self.url_kwargs)
|
38
|
+
else:
|
39
|
+
raise ValueError("RedirectView requires either url or url_name to be set")
|
40
|
+
|
41
|
+
args = self.request.meta.get("QUERY_STRING", "")
|
42
|
+
if args and self.preserve_query_params:
|
43
|
+
url = f"{url}?{args}"
|
44
|
+
return url
|
45
|
+
|
46
|
+
def get(self):
|
47
|
+
url = self.get_redirect_url()
|
48
|
+
return ResponseRedirect(url, status_code=self.status_code)
|
49
|
+
|
50
|
+
def head(self):
|
51
|
+
return self.get()
|
52
|
+
|
53
|
+
def post(self):
|
54
|
+
return self.get()
|
55
|
+
|
56
|
+
def options(self):
|
57
|
+
return self.get()
|
58
|
+
|
59
|
+
def delete(self):
|
60
|
+
return self.get()
|
61
|
+
|
62
|
+
def put(self):
|
63
|
+
return self.get()
|
64
|
+
|
65
|
+
def patch(self):
|
66
|
+
return self.get()
|
@@ -1,77 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
|
3
|
-
from plain.http import (
|
4
|
-
ResponseGone,
|
5
|
-
ResponsePermanentRedirect,
|
6
|
-
ResponseRedirect,
|
7
|
-
)
|
8
|
-
from plain.urls import reverse
|
9
|
-
|
10
|
-
from .base import View
|
11
|
-
|
12
|
-
logger = logging.getLogger("plain.request")
|
13
|
-
|
14
|
-
|
15
|
-
class RedirectView(View):
|
16
|
-
"""Provide a redirect on any GET request."""
|
17
|
-
|
18
|
-
permanent = False
|
19
|
-
url: str | None = None
|
20
|
-
pattern_name: str | None = None
|
21
|
-
query_string = False
|
22
|
-
|
23
|
-
def __init__(self, url=None, permanent=None):
|
24
|
-
# Allow url and permanent to be set in RedirectView.as_view(url="...", permanent=True)
|
25
|
-
self.url = url or self.url
|
26
|
-
self.permanent = permanent if permanent is not None else self.permanent
|
27
|
-
|
28
|
-
def get_redirect_url(self):
|
29
|
-
"""
|
30
|
-
Return the URL redirect to. Keyword arguments from the URL pattern
|
31
|
-
match generating the redirect request are provided as kwargs to this
|
32
|
-
method.
|
33
|
-
"""
|
34
|
-
if self.url:
|
35
|
-
url = self.url % self.url_kwargs
|
36
|
-
elif self.pattern_name:
|
37
|
-
url = reverse(self.pattern_name, *self.url_args, **self.url_kwargs)
|
38
|
-
else:
|
39
|
-
return None
|
40
|
-
|
41
|
-
args = self.request.meta.get("QUERY_STRING", "")
|
42
|
-
if args and self.query_string:
|
43
|
-
url = f"{url}?{args}"
|
44
|
-
return url
|
45
|
-
|
46
|
-
def get(self):
|
47
|
-
url = self.get_redirect_url()
|
48
|
-
if url:
|
49
|
-
if self.permanent:
|
50
|
-
return ResponsePermanentRedirect(url)
|
51
|
-
else:
|
52
|
-
return ResponseRedirect(url)
|
53
|
-
else:
|
54
|
-
logger.warning(
|
55
|
-
"Gone: %s",
|
56
|
-
self.request.path,
|
57
|
-
extra={"status_code": 410, "request": self.request},
|
58
|
-
)
|
59
|
-
return ResponseGone()
|
60
|
-
|
61
|
-
def head(self):
|
62
|
-
return self.get()
|
63
|
-
|
64
|
-
def post(self):
|
65
|
-
return self.get()
|
66
|
-
|
67
|
-
def options(self):
|
68
|
-
return self.get()
|
69
|
-
|
70
|
-
def delete(self):
|
71
|
-
return self.get()
|
72
|
-
|
73
|
-
def put(self):
|
74
|
-
return self.get()
|
75
|
-
|
76
|
-
def patch(self):
|
77
|
-
return self.get()
|
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
|