mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-09 03:03:41 +00:00
!refactor(backend): remove backwards-compatible urls (#11667)
* !refactor(backend): remove backwards-compatible urls * add changelog entry * remove mention of CUI * remove now unneeded test * fix link
This commit is contained in:
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- [#11111](https://github.com/inventree/InvenTree/pull/11111) - removes legacy metadata APIs
|
- [#11111](https://github.com/inventree/InvenTree/pull/11111) - removes legacy metadata APIs
|
||||||
- [#9814](https://github.com/inventree/InvenTree/pull/9814) - removes legacy config path support
|
- [#9814](https://github.com/inventree/InvenTree/pull/9814) - removes legacy config path support
|
||||||
|
- [#11667](https://github.com/inventree/InvenTree/pull/11667) - removes legacy url patterns
|
||||||
|
|
||||||
|
|
||||||
## Unreleased - YYYY-MM-DD
|
## Unreleased - YYYY-MM-DD
|
||||||
|
|||||||
@@ -514,7 +514,6 @@ Set the `INVENTREE_FRONTEND_SETTINGS` Environment variable to a JSON object or u
|
|||||||
| `debug` | Set the debug mode | *Server debug mode* |
|
| `debug` | Set the debug mode | *Server debug mode* |
|
||||||
| `environment` | `development` or `production` | *development if Server is in debug mode* |
|
| `environment` | `development` or `production` | *development if Server is in debug mode* |
|
||||||
| `show_server_selector` | In debug mode, show server selector by default. If no servers are specified, show server selector. | |
|
| `show_server_selector` | In debug mode, show server selector by default. If no servers are specified, show server selector. | |
|
||||||
| `url_compatibility` | Support compatibility with "legacy" URLs? | `true` |
|
|
||||||
| `sentry_dsn` | Set a Sentry DSN url | *Not specified* |
|
| `sentry_dsn` | Set a Sentry DSN url | *Not specified* |
|
||||||
| `mobile_mode` | Controls if InvenTree web UI can be used by mobile devices. There are 3 options: `default` - does not allow mobile devices; `allow-ignore` - shows a mobile device detected banner with a button to ignore this warning AT THE USERS OWN RISK; `allow-always` - skips the mobile check and allows mobile devices always (of course at the server admins OWN RISK) | `default` |
|
| `mobile_mode` | Controls if InvenTree web UI can be used by mobile devices. There are 3 options: `default` - does not allow mobile devices; `allow-ignore` - shows a mobile device detected banner with a button to ignore this warning AT THE USERS OWN RISK; `allow-always` - skips the mobile check and allows mobile devices always (of course at the server admins OWN RISK) | `default` |
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ InvenTree uses the [Redis](https://redis.io/) cache server to manage cache data.
|
|||||||
|
|
||||||
!!! info "Redis on Docker"
|
!!! info "Redis on Docker"
|
||||||
Docker adds an additional network layer - that might lead to lower performance than bare metal.
|
Docker adds an additional network layer - that might lead to lower performance than bare metal.
|
||||||
To optimize and configure your redis deployment follow the [official docker guide](https://redis.io/docs/getting-started/install-stack/docker/#configuration).
|
To optimize and configure your redis deployment follow the [official docker guide](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/docker/).
|
||||||
|
|
||||||
!!! tip "Enable Cache"
|
!!! tip "Enable Cache"
|
||||||
While a redis container is provided in the default configuration, by default it is not enabled in the InvenTree server. You can enable redis cache support by following the [caching configuration guide](./config.md#caching)
|
While a redis container is provided in the default configuration, by default it is not enabled in the InvenTree server. You can enable redis cache support by following the [caching configuration guide](./config.md#caching)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ A stock location represents a physical real-world location where *Stock Items* a
|
|||||||
|
|
||||||
### Icons
|
### Icons
|
||||||
|
|
||||||
Stock locations can be assigned custom icons (either directly or through [Stock Location Types](#stock-location-type)). In the web interface there is a custom icon picker component available that can help to select the right icon. However in CUI the icon needs to be entered manually.
|
Stock locations can be assigned custom icons (either directly or through [Stock Location Types](#stock-location-type)). In the web interface there is a custom icon picker component available that can help to select the right icon.
|
||||||
|
|
||||||
By default, the tabler icons package (with prefix: `ti`) is available. To manually select an item, search on the [tabler icons](https://tabler.io/icons) page for an icon and copy its name e.g. `bookmark`. Some icons have a filled and an outline version (if no variants are specified, it's an outline variant). Now these values can be put into the format: `<package-prefix>:<icon-name>:<variant>`. E.g. `ti:bookmark:outline` or `ti:bookmark:filled`.
|
By default, the tabler icons package (with prefix: `ti`) is available. To manually select an item, search on the [tabler icons](https://tabler.io/icons) page for an icon and copy its name e.g. `bookmark`. Some icons have a filled and an outline version (if no variants are specified, it's an outline variant). Now these values can be put into the format: `<package-prefix>:<icon-name>:<variant>`. E.g. `ti:bookmark:outline` or `ti:bookmark:filled`.
|
||||||
|
|
||||||
|
|||||||
@@ -565,15 +565,6 @@ def get_frontend_settings(debug=True):
|
|||||||
# If no servers are specified, show server selector
|
# If no servers are specified, show server selector
|
||||||
frontend_settings['show_server_selector'] = True
|
frontend_settings['show_server_selector'] = True
|
||||||
|
|
||||||
# Support compatibility with "legacy" URLs?
|
|
||||||
try:
|
|
||||||
frontend_settings['url_compatibility'] = bool(
|
|
||||||
frontend_settings.get('url_compatibility', True)
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
# If the value is not a boolean, set it to True
|
|
||||||
frontend_settings['url_compatibility'] = True
|
|
||||||
|
|
||||||
return frontend_settings
|
return frontend_settings
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1789,25 +1789,3 @@ class SchemaPostprocessingTest(TestCase):
|
|||||||
self.assertNotIn('customer_detail', schemas_out.get('SalesOrder')['required'])
|
self.assertNotIn('customer_detail', schemas_out.get('SalesOrder')['required'])
|
||||||
# required key removed when empty
|
# required key removed when empty
|
||||||
self.assertNotIn('required', schemas_out.get('SalesOrderShipment'))
|
self.assertNotIn('required', schemas_out.get('SalesOrderShipment'))
|
||||||
|
|
||||||
|
|
||||||
class URLCompatibilityTest(InvenTreeTestCase):
|
|
||||||
"""Unit test for legacy URL compatibility."""
|
|
||||||
|
|
||||||
URL_MAPPINGS = [
|
|
||||||
('/index/', '/web'),
|
|
||||||
('/part/1/', '/web/part/1/'),
|
|
||||||
('/company/customers/', '/web/sales/index/customers'),
|
|
||||||
('/build/3/', '/web/manufacturing/build-order/3'),
|
|
||||||
('/stock/item/1/', '/web/stock/item/1/'),
|
|
||||||
]
|
|
||||||
|
|
||||||
@override_settings(
|
|
||||||
SITE_URL='http://testserver', CSRF_TRUSTED_ORIGINS=['http://testserver']
|
|
||||||
)
|
|
||||||
def test_legacy_urls(self):
|
|
||||||
"""Test legacy URLs."""
|
|
||||||
for old_url, new_url in self.URL_MAPPINGS:
|
|
||||||
response = self.client.get(old_url)
|
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
self.assertEqual(response['Location'], new_url)
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import report.api
|
|||||||
import stock.api
|
import stock.api
|
||||||
import users.api
|
import users.api
|
||||||
from plugin.urls import get_plugin_urls
|
from plugin.urls import get_plugin_urls
|
||||||
from web.urls import cui_compatibility_urls
|
|
||||||
from web.urls import urlpatterns as platform_urls
|
from web.urls import urlpatterns as platform_urls
|
||||||
|
|
||||||
from .api import (
|
from .api import (
|
||||||
@@ -182,10 +181,6 @@ urlpatterns.append(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compatibility layer for old (CUI) URLs
|
|
||||||
if settings.FRONTEND_SETTINGS.get('url_compatibility'):
|
|
||||||
urlpatterns += cui_compatibility_urls(settings.FRONTEND_URL_BASE)
|
|
||||||
|
|
||||||
if settings.DJANGO_SILK_ENABLED:
|
if settings.DJANGO_SILK_ENABLED:
|
||||||
urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]
|
urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]
|
||||||
|
|
||||||
|
|||||||
@@ -3,131 +3,10 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.urls import include, path, re_path
|
from django.urls import include, path, re_path
|
||||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||||
from django.views.generic import RedirectView, TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
spa_view = ensure_csrf_cookie(TemplateView.as_view(template_name='web/index.html'))
|
spa_view = ensure_csrf_cookie(TemplateView.as_view(template_name='web/index.html'))
|
||||||
|
|
||||||
|
|
||||||
def cui_compatibility_urls(base: str) -> list:
|
|
||||||
"""Generate a list of URL patterns for compatibility with old (CUI) URLs.
|
|
||||||
|
|
||||||
These URLs are provided for backwards compatibility with older versions of InvenTree,
|
|
||||||
before we moved to a SPA (Single Page Application) architecture in the 1.0.0 release.
|
|
||||||
|
|
||||||
At some future point these may be removed?
|
|
||||||
|
|
||||||
Args:
|
|
||||||
base (str): The base URL to use for generating the patterns.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: A list of URL patterns.
|
|
||||||
"""
|
|
||||||
return [
|
|
||||||
# Old 'index' view - reroute to the dashboard
|
|
||||||
path('index/', RedirectView.as_view(url=f'/{base}')),
|
|
||||||
path('settings/', RedirectView.as_view(url=f'/{base}/settings')),
|
|
||||||
# Company patterns
|
|
||||||
path(
|
|
||||||
'company/',
|
|
||||||
include([
|
|
||||||
path(
|
|
||||||
'customers/',
|
|
||||||
RedirectView.as_view(url=f'/{base}/sales/index/customers'),
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'manufacturers/',
|
|
||||||
RedirectView.as_view(url=f'/{base}/purchasing/index/manufacturers'),
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'suppliers/',
|
|
||||||
RedirectView.as_view(url=f'/{base}/purchasing/index/suppliers'),
|
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
r'(?P<pk>\d+)/', RedirectView.as_view(url=f'/{base}/company/%(pk)s')
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
# "Part" app views
|
|
||||||
re_path(
|
|
||||||
r'^part/(?P<path>.*)$', RedirectView.as_view(url=f'/{base}/part/%(path)s')
|
|
||||||
),
|
|
||||||
# "Stock" app views
|
|
||||||
re_path(
|
|
||||||
r'^stock/(?P<path>.*)$', RedirectView.as_view(url=f'/{base}/stock/%(path)s')
|
|
||||||
),
|
|
||||||
# "Build" app views (requires some custom handling)
|
|
||||||
path(
|
|
||||||
'build/',
|
|
||||||
include([
|
|
||||||
re_path(
|
|
||||||
r'^(?P<pk>\d+)/',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/manufacturing/build-order/%(pk)s'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
re_path('.*', RedirectView.as_view(url=f'/{base}/manufacturing/')),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
# "Order" app views
|
|
||||||
path(
|
|
||||||
'order/',
|
|
||||||
include([
|
|
||||||
path(
|
|
||||||
'purchase-order/',
|
|
||||||
include([
|
|
||||||
re_path(
|
|
||||||
r'^(?P<pk>\d+)/',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/purchasing/purchase-order/%(pk)s'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
'.*',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/purchasing/index/purchaseorders/'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'sales-order/',
|
|
||||||
include([
|
|
||||||
re_path(
|
|
||||||
r'^(?P<pk>\d+)/',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/sales/sales-order/%(pk)s'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
'.*',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/sales/index/salesorders/'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'return-order/',
|
|
||||||
include([
|
|
||||||
re_path(
|
|
||||||
r'^(?P<pk>\d+)/',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/sales/return-order/%(pk)s'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
'.*',
|
|
||||||
RedirectView.as_view(
|
|
||||||
url=f'/{base}/sales/index/returnorders/'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(
|
path(
|
||||||
f'{settings.FRONTEND_URL_BASE}/',
|
f'{settings.FRONTEND_URL_BASE}/',
|
||||||
|
|||||||
Reference in New Issue
Block a user