Move more paths to basic path (#6251)

* move more paths to basic path

* changed url route to only match fully - fixed test

* revert path changes on labelprint pages

* fix not found/redirect

* revert test change
This commit is contained in:
Matthias Mair 2024-01-18 06:05:10 +00:00 committed by GitHub
parent c3a5d777b1
commit b8b3dfc90e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 684 additions and 798 deletions

View File

@ -7,7 +7,7 @@ from django.conf import settings
from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import Resolver404, include, re_path, resolve, reverse_lazy
from django.urls import Resolver404, include, path, resolve, reverse_lazy
from allauth_2fa.middleware import AllauthTwoFactorMiddleware, BaseRequire2FAMiddleware
from error_report.middleware import ExceptionProcessor
@ -124,7 +124,7 @@ class AuthRequiredMiddleware(object):
return response
url_matcher = re_path('', include(frontendpatterns))
url_matcher = path('', include(frontendpatterns))
class Check2FAMiddleware(BaseRequire2FAMiddleware):

View File

@ -73,23 +73,23 @@ admin.site.site_header = 'InvenTree Admin'
apipatterns = [
# Global search
path('search/', APISearchView.as_view(), name='api-search'),
re_path(r'^settings/', include(common.api.settings_api_urls)),
re_path(r'^part/', include(part.api.part_api_urls)),
re_path(r'^bom/', include(part.api.bom_api_urls)),
re_path(r'^company/', include(company.api.company_api_urls)),
re_path(r'^stock/', include(stock.api.stock_api_urls)),
re_path(r'^build/', include(build.api.build_api_urls)),
re_path(r'^order/', include(order.api.order_api_urls)),
re_path(r'^label/', include(label.api.label_api_urls)),
re_path(r'^report/', include(report.api.report_api_urls)),
re_path(r'^user/', include(users.api.user_urls)),
re_path(r'^admin/', include(common.api.admin_api_urls)),
path('settings/', include(common.api.settings_api_urls)),
path('part/', include(part.api.part_api_urls)),
path('bom/', include(part.api.bom_api_urls)),
path('company/', include(company.api.company_api_urls)),
path('stock/', include(stock.api.stock_api_urls)),
path('build/', include(build.api.build_api_urls)),
path('order/', include(order.api.order_api_urls)),
path('label/', include(label.api.label_api_urls)),
path('report/', include(report.api.report_api_urls)),
path('user/', include(users.api.user_urls)),
path('admin/', include(common.api.admin_api_urls)),
# Plugin endpoints
path('', include(plugin.api.plugin_api_urls)),
# Common endpoints endpoint
path('', include(common.api.common_api_urls)),
# OpenAPI Schema
re_path(
path(
'schema/',
SpectacularAPIView.as_view(custom_settings={'SCHEMA_PATH_PREFIX': '/api/'}),
name='schema',
@ -163,13 +163,11 @@ apipatterns = [
]
settings_urls = [
re_path(r'^i18n/?', include('django.conf.urls.i18n')),
re_path(
r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'
),
path('i18n/', include('django.conf.urls.i18n')),
path('appearance/', AppearanceSelectView.as_view(), name='settings-appearance'),
# Catch any other urls
re_path(
r'^.*$',
path(
'',
SettingsView.as_view(template_name='InvenTree/settings/settings.html'),
name='settings',
),
@ -177,28 +175,28 @@ settings_urls = [
notifications_urls = [
# Catch any other urls
re_path(r'^.*$', NotificationsView.as_view(), name='notifications')
path('', NotificationsView.as_view(), name='notifications')
]
# These javascript files are served "dynamically" - i.e. rendered on demand
dynamic_javascript_urls = [
re_path(
r'^calendar.js',
path(
'calendar.js',
DynamicJsView.as_view(template_name='js/dynamic/calendar.js'),
name='calendar.js',
),
re_path(
r'^nav.js',
path(
'nav.js',
DynamicJsView.as_view(template_name='js/dynamic/nav.js'),
name='nav.js',
),
re_path(
r'^permissions.js',
path(
'permissions.js',
DynamicJsView.as_view(template_name='js/dynamic/permissions.js'),
name='permissions.js',
),
re_path(
r'^settings.js',
path(
'settings.js',
DynamicJsView.as_view(template_name='js/dynamic/settings.js'),
name='settings.js',
),
@ -206,148 +204,148 @@ dynamic_javascript_urls = [
# These javascript files are passed through the Django translation layer
translated_javascript_urls = [
re_path(
r'^api.js',
path(
'api.js',
DynamicJsView.as_view(template_name='js/translated/api.js'),
name='api.js',
),
re_path(
r'^attachment.js',
path(
'attachment.js',
DynamicJsView.as_view(template_name='js/translated/attachment.js'),
name='attachment.js',
),
re_path(
r'^barcode.js',
path(
'barcode.js',
DynamicJsView.as_view(template_name='js/translated/barcode.js'),
name='barcode.js',
),
re_path(
r'^bom.js',
path(
'bom.js',
DynamicJsView.as_view(template_name='js/translated/bom.js'),
name='bom.js',
),
re_path(
r'^build.js',
path(
'build.js',
DynamicJsView.as_view(template_name='js/translated/build.js'),
name='build.js',
),
re_path(
r'^charts.js',
path(
'charts.js',
DynamicJsView.as_view(template_name='js/translated/charts.js'),
name='charts.js',
),
re_path(
r'^company.js',
path(
'company.js',
DynamicJsView.as_view(template_name='js/translated/company.js'),
name='company.js',
),
re_path(
r'^filters.js',
path(
'filters.js',
DynamicJsView.as_view(template_name='js/translated/filters.js'),
name='filters.js',
),
re_path(
r'^forms.js',
path(
'forms.js',
DynamicJsView.as_view(template_name='js/translated/forms.js'),
name='forms.js',
),
re_path(
r'^helpers.js',
path(
'helpers.js',
DynamicJsView.as_view(template_name='js/translated/helpers.js'),
name='helpers.js',
),
re_path(
r'^index.js',
path(
'index.js',
DynamicJsView.as_view(template_name='js/translated/index.js'),
name='index.js',
),
re_path(
r'^label.js',
path(
'label.js',
DynamicJsView.as_view(template_name='js/translated/label.js'),
name='label.js',
),
re_path(
r'^model_renderers.js',
path(
'model_renderers.js',
DynamicJsView.as_view(template_name='js/translated/model_renderers.js'),
name='model_renderers.js',
),
re_path(
r'^modals.js',
path(
'modals.js',
DynamicJsView.as_view(template_name='js/translated/modals.js'),
name='modals.js',
),
re_path(
r'^order.js',
path(
'order.js',
DynamicJsView.as_view(template_name='js/translated/order.js'),
name='order.js',
),
re_path(
r'^part.js',
path(
'part.js',
DynamicJsView.as_view(template_name='js/translated/part.js'),
name='part.js',
),
re_path(
r'^purchase_order.js',
path(
'purchase_order.js',
DynamicJsView.as_view(template_name='js/translated/purchase_order.js'),
name='purchase_order.js',
),
re_path(
r'^return_order.js',
path(
'return_order.js',
DynamicJsView.as_view(template_name='js/translated/return_order.js'),
name='return_order.js',
),
re_path(
r'^report.js',
path(
'report.js',
DynamicJsView.as_view(template_name='js/translated/report.js'),
name='report.js',
),
re_path(
r'^sales_order.js',
path(
'sales_order.js',
DynamicJsView.as_view(template_name='js/translated/sales_order.js'),
name='sales_order.js',
),
re_path(
r'^search.js',
path(
'search.js',
DynamicJsView.as_view(template_name='js/translated/search.js'),
name='search.js',
),
re_path(
r'^stock.js',
path(
'stock.js',
DynamicJsView.as_view(template_name='js/translated/stock.js'),
name='stock.js',
),
re_path(
r'^status_codes.js',
path(
'status_codes.js',
DynamicJsView.as_view(template_name='js/translated/status_codes.js'),
name='status_codes.js',
),
re_path(
r'^plugin.js',
path(
'plugin.js',
DynamicJsView.as_view(template_name='js/translated/plugin.js'),
name='plugin.js',
),
re_path(
r'^pricing.js',
path(
'pricing.js',
DynamicJsView.as_view(template_name='js/translated/pricing.js'),
name='pricing.js',
),
re_path(
r'^news.js',
path(
'news.js',
DynamicJsView.as_view(template_name='js/translated/news.js'),
name='news.js',
),
re_path(
r'^tables.js',
path(
'tables.js',
DynamicJsView.as_view(template_name='js/translated/tables.js'),
name='tables.js',
),
re_path(
r'^table_filters.js',
path(
'table_filters.js',
DynamicJsView.as_view(template_name='js/translated/table_filters.js'),
name='table_filters.js',
),
re_path(
r'^notification.js',
path(
'notification.js',
DynamicJsView.as_view(template_name='js/translated/notification.js'),
name='notification.js',
),
@ -355,34 +353,32 @@ translated_javascript_urls = [
backendpatterns = [
# "Dynamic" javascript files which are rendered using InvenTree templating.
re_path(r'^js/dynamic/', include(dynamic_javascript_urls)),
re_path(r'^js/i18n/', include(translated_javascript_urls)),
re_path(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
re_path(r'^auth/?', auth_request),
re_path(r'^api/', include(apipatterns)),
re_path(
r'^api-doc/', SpectacularRedocView.as_view(url_name='schema'), name='api-doc'
),
path('js/dynamic/', include(dynamic_javascript_urls)),
path('js/i18n/', include(translated_javascript_urls)),
path('auth/', include('rest_framework.urls', namespace='rest_framework')),
path('auth/', auth_request),
path('api/', include(apipatterns)),
path('api-doc/', SpectacularRedocView.as_view(url_name='schema'), name='api-doc'),
]
classic_frontendpatterns = [
# Apps
re_path(r'^build/', include(build_urls)),
re_path(r'^common/', include(common_urls)),
re_path(r'^company/', include(company_urls)),
re_path(r'^order/', include(order_urls)),
re_path(r'^manufacturer-part/', include(manufacturer_part_urls)),
re_path(r'^part/', include(part_urls)),
re_path(r'^stock/', include(stock_urls)),
re_path(r'^supplier-part/', include(supplier_part_urls)),
re_path(r'^edit-user/', EditUserView.as_view(), name='edit-user'),
re_path(r'^set-password/', SetPasswordView.as_view(), name='set-password'),
re_path(r'^index/', IndexView.as_view(), name='index'),
re_path(r'^notifications/', include(notifications_urls)),
re_path(r'^search/', SearchView.as_view(), name='search'),
re_path(r'^settings/', include(settings_urls)),
re_path(r'^about/', AboutView.as_view(), name='about'),
re_path(r'^stats/', DatabaseStatsView.as_view(), name='stats'),
path('build/', include(build_urls)),
path('common/', include(common_urls)),
path('company/', include(company_urls)),
path('order/', include(order_urls)),
path('manufacturer-part/', include(manufacturer_part_urls)),
path('part/', include(part_urls)),
path('stock/', include(stock_urls)),
path('supplier-part/', include(supplier_part_urls)),
path('edit-user/', EditUserView.as_view(), name='edit-user'),
path('set-password/', SetPasswordView.as_view(), name='set-password'),
path('index/', IndexView.as_view(), name='index'),
path('notifications/', include(notifications_urls)),
path('search/', SearchView.as_view(), name='search'),
path('settings/', include(settings_urls)),
path('about/', AboutView.as_view(), name='about'),
path('stats/', DatabaseStatsView.as_view(), name='stats'),
# DB user sessions
path(
'accounts/sessions/other/delete/',
@ -396,9 +392,9 @@ classic_frontendpatterns = [
),
# Single Sign On / allauth
# overrides of urlpatterns
re_path(r'^accounts/email/', CustomEmailView.as_view(), name='account_email'),
re_path(
r'^accounts/social/connections/',
path('accounts/email/', CustomEmailView.as_view(), name='account_email'),
path(
'accounts/social/connections/',
CustomConnectionsView.as_view(),
name='socialaccount_connections',
),
@ -408,9 +404,9 @@ classic_frontendpatterns = [
name='account_reset_password_from_key',
),
# Override login page
re_path('accounts/login/', CustomLoginView.as_view(), name='account_login'),
re_path(r'^accounts/', include('allauth_2fa.urls')), # MFA support
re_path(r'^accounts/', include('allauth.urls')), # included urlpatterns
path('accounts/login/', CustomLoginView.as_view(), name='account_login'),
path('accounts/', include('allauth_2fa.urls')), # MFA support
path('accounts/', include('allauth.urls')), # included urlpatterns
]
urlpatterns = []

View File

@ -1,7 +1,7 @@
"""JSON API for the Build app."""
from django.db.models import F, Q
from django.urls import include, path, re_path
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
@ -587,44 +587,44 @@ class BuildAttachmentDetail(AttachmentMixin, RetrieveUpdateDestroyAPI):
build_api_urls = [
# Attachments
re_path(r'^attachment/', include([
path(r'<int:pk>/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'),
re_path(r'^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'),
path('attachment/', include([
path('<int:pk>/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'),
path('', BuildAttachmentList.as_view(), name='api-build-attachment-list'),
])),
# Build lines
re_path(r'^line/', include([
path(r'<int:pk>/', BuildLineDetail.as_view(), name='api-build-line-detail'),
re_path(r'^.*$', BuildLineList.as_view(), name='api-build-line-list'),
path('line/', include([
path('<int:pk>/', BuildLineDetail.as_view(), name='api-build-line-detail'),
path('', BuildLineList.as_view(), name='api-build-line-list'),
])),
# Build Items
re_path(r'^item/', include([
path(r'<int:pk>/', include([
re_path(r'^metadata/', MetadataView.as_view(), {'model': BuildItem}, name='api-build-item-metadata'),
re_path(r'^.*$', BuildItemDetail.as_view(), name='api-build-item-detail'),
path('item/', include([
path('<int:pk>/', include([
path('metadata/', MetadataView.as_view(), {'model': BuildItem}, name='api-build-item-metadata'),
path('', BuildItemDetail.as_view(), name='api-build-item-detail'),
])),
re_path(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'),
path('', BuildItemList.as_view(), name='api-build-item-list'),
])),
# Build Detail
path(r'<int:pk>/', include([
re_path(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'),
re_path(r'^auto-allocate/', BuildAutoAllocate.as_view(), name='api-build-auto-allocate'),
re_path(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'),
re_path(r'^create-output/', BuildOutputCreate.as_view(), name='api-build-output-create'),
re_path(r'^delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'),
re_path(r'^scrap-outputs/', BuildOutputScrap.as_view(), name='api-build-output-scrap'),
re_path(r'^finish/', BuildFinish.as_view(), name='api-build-finish'),
re_path(r'^cancel/', BuildCancel.as_view(), name='api-build-cancel'),
re_path(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
re_path(r'^metadata/', MetadataView.as_view(), {'model': Build}, name='api-build-metadata'),
re_path(r'^.*$', BuildDetail.as_view(), name='api-build-detail'),
path('<int:pk>/', include([
path('allocate/', BuildAllocate.as_view(), name='api-build-allocate'),
path('auto-allocate/', BuildAutoAllocate.as_view(), name='api-build-auto-allocate'),
path('complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'),
path('create-output/', BuildOutputCreate.as_view(), name='api-build-output-create'),
path('delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'),
path('scrap-outputs/', BuildOutputScrap.as_view(), name='api-build-output-scrap'),
path('finish/', BuildFinish.as_view(), name='api-build-finish'),
path('cancel/', BuildCancel.as_view(), name='api-build-cancel'),
path('unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
path('metadata/', MetadataView.as_view(), {'model': Build}, name='api-build-metadata'),
path('', BuildDetail.as_view(), name='api-build-detail'),
])),
# Build order status code information
re_path(r'status/', StatusView.as_view(), {StatusView.MODEL_REF: BuildStatus}, name='api-build-status-codes'),
path('status/', StatusView.as_view(), {StatusView.MODEL_REF: BuildStatus}, name='api-build-status-codes'),
# Build List
re_path(r'^.*$', BuildList.as_view(), name='api-build-list'),
path('', BuildList.as_view(), name='api-build-list'),
]

View File

@ -1,15 +1,15 @@
"""URL lookup for Build app."""
from django.urls import include, path, re_path
from django.urls import include, path
from . import views
build_urls = [
path(r'<int:pk>/', include([
re_path(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
path('<int:pk>/', include([
path('', views.BuildDetail.as_view(), name='build-detail'),
])),
re_path(r'.*$', views.BuildIndex.as_view(), name='build-index'),
path('', views.BuildIndex.as_view(), name='build-index'),
]

View File

@ -600,8 +600,8 @@ class FlagDetail(RetrieveAPI):
settings_api_urls = [
# User settings
re_path(
r'^user/',
path(
'user/',
include([
# User Settings Detail
re_path(
@ -610,30 +610,30 @@ settings_api_urls = [
name='api-user-setting-detail',
),
# User Settings List
re_path(r'^.*$', UserSettingsList.as_view(), name='api-user-setting-list'),
path('', UserSettingsList.as_view(), name='api-user-setting-list'),
]),
),
# Notification settings
re_path(
r'^notification/',
path(
'notification/',
include([
# Notification Settings Detail
path(
r'<int:pk>/',
'<int:pk>/',
NotificationUserSettingsDetail.as_view(),
name='api-notification-setting-detail',
),
# Notification Settings List
re_path(
r'^.*$',
path(
'',
NotificationUserSettingsList.as_view(),
name='api-notification-setting-list',
),
]),
),
# Global settings
re_path(
r'^global/',
path(
'global/',
include([
# Global Settings Detail
re_path(
@ -642,9 +642,7 @@ settings_api_urls = [
name='api-global-setting-detail',
),
# Global Settings List
re_path(
r'^.*$', GlobalSettingsList.as_view(), name='api-global-setting-list'
),
path('', GlobalSettingsList.as_view(), name='api-global-setting-list'),
]),
),
]
@ -653,127 +651,105 @@ common_api_urls = [
# Webhooks
path('webhook/<slug:endpoint>/', WebhookView.as_view(), name='api-webhook'),
# Uploaded images for notes
re_path(
r'^notes-image-upload/', NotesImageList.as_view(), name='api-notes-image-list'
),
path('notes-image-upload/', NotesImageList.as_view(), name='api-notes-image-list'),
# Background task information
re_path(
r'^background-task/',
path(
'background-task/',
include([
re_path(
r'^pending/', PendingTaskList.as_view(), name='api-pending-task-list'
),
re_path(
r'^scheduled/',
path('pending/', PendingTaskList.as_view(), name='api-pending-task-list'),
path(
'scheduled/',
ScheduledTaskList.as_view(),
name='api-scheduled-task-list',
),
re_path(r'^failed/', FailedTaskList.as_view(), name='api-failed-task-list'),
re_path(
r'^.*$', BackgroundTaskOverview.as_view(), name='api-task-overview'
),
path('failed/', FailedTaskList.as_view(), name='api-failed-task-list'),
path('', BackgroundTaskOverview.as_view(), name='api-task-overview'),
]),
),
# Project codes
re_path(
r'^project-code/',
path(
'project-code/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': common.models.ProjectCode},
name='api-project-code-metadata',
),
re_path(
r'^.*$',
ProjectCodeDetail.as_view(),
name='api-project-code-detail',
path(
'', ProjectCodeDetail.as_view(), name='api-project-code-detail'
),
]),
),
re_path(r'^.*$', ProjectCodeList.as_view(), name='api-project-code-list'),
path('', ProjectCodeList.as_view(), name='api-project-code-list'),
]),
),
# Custom physical units
re_path(
r'^units/',
path(
'units/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^.*$',
CustomUnitDetail.as_view(),
name='api-custom-unit-detail',
)
path('', CustomUnitDetail.as_view(), name='api-custom-unit-detail')
]),
),
re_path(r'^.*$', CustomUnitList.as_view(), name='api-custom-unit-list'),
path('', CustomUnitList.as_view(), name='api-custom-unit-list'),
]),
),
# Currencies
re_path(
r'^currency/',
path(
'currency/',
include([
re_path(
r'^exchange/',
path(
'exchange/',
CurrencyExchangeView.as_view(),
name='api-currency-exchange',
),
re_path(
r'^refresh/', CurrencyRefreshView.as_view(), name='api-currency-refresh'
path(
'refresh/', CurrencyRefreshView.as_view(), name='api-currency-refresh'
),
]),
),
# Notifications
re_path(
r'^notifications/',
path(
'notifications/',
include([
# Individual purchase order detail URLs
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'.*$',
path(
'',
NotificationDetail.as_view(),
name='api-notifications-detail',
)
]),
),
# Read all
re_path(
r'^readall/',
path(
'readall/',
NotificationReadAll.as_view(),
name='api-notifications-readall',
),
# Notification messages list
re_path(r'^.*$', NotificationList.as_view(), name='api-notifications-list'),
path('', NotificationList.as_view(), name='api-notifications-list'),
]),
),
# News
re_path(
r'^news/',
path(
'news/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'.*$', NewsFeedEntryDetail.as_view(), name='api-news-detail'
)
path('', NewsFeedEntryDetail.as_view(), name='api-news-detail')
]),
),
re_path(r'^.*$', NewsFeedEntryList.as_view(), name='api-news-list'),
]),
),
# Error information
re_path(
r'^error-report/',
include([
path(r'<int:pk>/', ErrorMessageDetail.as_view(), name='api-error-detail'),
re_path(r'^.*$', ErrorMessageList.as_view(), name='api-error-list'),
path('', NewsFeedEntryList.as_view(), name='api-news-list'),
]),
),
# Flags
@ -781,7 +757,7 @@ common_api_urls = [
'flags/',
include([
path('<str:key>/', FlagDetail.as_view(), name='api-flag-detail'),
re_path(r'^.*$', FlagList.as_view(), name='api-flag-list'),
path('', FlagList.as_view(), name='api-flag-list'),
]),
),
# Status

View File

@ -484,32 +484,32 @@ class SupplierPriceBreakDetail(RetrieveUpdateDestroyAPI):
manufacturer_part_api_urls = [
# Base URL for ManufacturerPartAttachment API endpoints
re_path(
r'^attachment/',
path(
'attachment/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
ManufacturerPartAttachmentDetail.as_view(),
name='api-manufacturer-part-attachment-detail',
),
re_path(
r'^$',
path(
'',
ManufacturerPartAttachmentList.as_view(),
name='api-manufacturer-part-attachment-list',
),
]),
),
re_path(
r'^parameter/',
path(
'parameter/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
ManufacturerPartParameterDetail.as_view(),
name='api-manufacturer-part-parameter-detail',
),
# Catch anything else
re_path(
r'^.*$',
path(
'',
ManufacturerPartParameterList.as_view(),
name='api-manufacturer-part-parameter-list',
),
@ -518,21 +518,21 @@ manufacturer_part_api_urls = [
re_path(
r'^(?P<pk>\d+)/?',
include([
re_path(
'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': ManufacturerPart},
name='api-manufacturer-part-metadata',
),
re_path(
'^.*$',
path(
'',
ManufacturerPartDetail.as_view(),
name='api-manufacturer-part-detail',
),
]),
),
# Catch anything else
re_path(r'^.*$', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'),
path('', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'),
]
@ -540,36 +540,34 @@ supplier_part_api_urls = [
re_path(
r'^(?P<pk>\d+)/?',
include([
re_path(
'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': SupplierPart},
name='api-supplier-part-metadata',
),
re_path(
'^.*$', SupplierPartDetail.as_view(), name='api-supplier-part-detail'
),
path('', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
]),
),
# Catch anything else
re_path(r'^.*$', SupplierPartList.as_view(), name='api-supplier-part-list'),
path('', SupplierPartList.as_view(), name='api-supplier-part-list'),
]
company_api_urls = [
re_path(r'^part/manufacturer/', include(manufacturer_part_api_urls)),
re_path(r'^part/', include(supplier_part_api_urls)),
path('part/manufacturer/', include(manufacturer_part_api_urls)),
path('part/', include(supplier_part_api_urls)),
# Supplier price breaks
re_path(
r'^price-break/',
path(
'price-break/',
include([
re_path(
r'^(?P<pk>\d+)/?',
SupplierPriceBreakDetail.as_view(),
name='api-part-supplier-price-detail',
),
re_path(
r'^.*$',
path(
'',
SupplierPriceBreakList.as_view(),
name='api-part-supplier-price-list',
),
@ -578,54 +576,52 @@ company_api_urls = [
re_path(
r'^(?P<pk>\d+)/?',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': Company},
name='api-company-metadata',
),
re_path(r'^.*$', CompanyDetail.as_view(), name='api-company-detail'),
path('', CompanyDetail.as_view(), name='api-company-detail'),
]),
),
re_path(
r'^attachment/',
path(
'attachment/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
CompanyAttachmentDetail.as_view(),
name='api-company-attachment-detail',
),
re_path(
r'^$',
CompanyAttachmentList.as_view(),
name='api-company-attachment-list',
path(
'', CompanyAttachmentList.as_view(), name='api-company-attachment-list'
),
]),
),
re_path(
r'^contact/',
path(
'contact/',
include([
re_path(
r'^(?P<pk>\d+)/?',
include([
re_path(
'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': Contact},
name='api-contact-metadata',
),
re_path('^.*$', ContactDetail.as_view(), name='api-contact-detail'),
path('', ContactDetail.as_view(), name='api-contact-detail'),
]),
),
re_path(r'^.*$', ContactList.as_view(), name='api-contact-list'),
path('', ContactList.as_view(), name='api-contact-list'),
]),
),
re_path(
r'^address/',
path(
'address/',
include([
path('<int:pk>/', AddressDetail.as_view(), name='api-address-detail'),
re_path(r'^.*$', AddressList.as_view(), name='api-address-list'),
path('', AddressList.as_view(), name='api-address-list'),
]),
),
re_path(r'^.*$', CompanyList.as_view(), name='api-company-list'),
path('', CompanyList.as_view(), name='api-company-list'),
]

View File

@ -1,27 +1,25 @@
"""URL lookup for Company app."""
from django.urls import include, path, re_path
from django.urls import include, path
from . import views
company_urls = [
# Detail URLs for a specific Company instance
path(
r'<int:pk>/',
include([
re_path(r'^.*$', views.CompanyDetail.as_view(), name='company-detail')
]),
'<int:pk>/',
include([path('', views.CompanyDetail.as_view(), name='company-detail')]),
),
re_path(r'suppliers/', views.CompanyIndex.as_view(), name='supplier-index'),
re_path(r'manufacturers/', views.CompanyIndex.as_view(), name='manufacturer-index'),
re_path(r'customers/', views.CompanyIndex.as_view(), name='customer-index'),
path('suppliers/', views.CompanyIndex.as_view(), name='supplier-index'),
path('manufacturers/', views.CompanyIndex.as_view(), name='manufacturer-index'),
path('customers/', views.CompanyIndex.as_view(), name='customer-index'),
# Redirect any other patterns to the 'company' index which displays all companies
re_path(r'^.*$', views.CompanyIndex.as_view(), name='company-index'),
path('', views.CompanyIndex.as_view(), name='company-index'),
]
manufacturer_part_urls = [
path(
r'<int:pk>/',
'<int:pk>/',
views.ManufacturerPartDetail.as_view(
template_name='company/manufacturer_part.html'
),
@ -31,10 +29,10 @@ manufacturer_part_urls = [
supplier_part_urls = [
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
'^.*$',
path(
'',
views.SupplierPartDetail.as_view(
template_name='company/supplier_part.html'
),

View File

@ -372,129 +372,123 @@ class BuildLineLabelPrint(BuildLineLabelMixin, LabelPrintMixin, RetrieveAPI):
label_api_urls = [
# Stock item labels
re_path(
r'stock/',
path(
'stock/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
StockItemLabelPrint.as_view(),
name='api-stockitem-label-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': label.models.StockItemLabel},
name='api-stockitem-label-metadata',
),
re_path(
r'^.*$',
path(
'',
StockItemLabelDetail.as_view(),
name='api-stockitem-label-detail',
),
]),
),
# List view
re_path(
r'^.*$', StockItemLabelList.as_view(), name='api-stockitem-label-list'
),
path('', StockItemLabelList.as_view(), name='api-stockitem-label-list'),
]),
),
# Stock location labels
re_path(
r'location/',
path(
'location/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
StockLocationLabelPrint.as_view(),
name='api-stocklocation-label-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': label.models.StockLocationLabel},
name='api-stocklocation-label-metadata',
),
re_path(
r'^.*$',
path(
'',
StockLocationLabelDetail.as_view(),
name='api-stocklocation-label-detail',
),
]),
),
# List view
re_path(
r'^.*$',
path(
'',
StockLocationLabelList.as_view(),
name='api-stocklocation-label-list',
),
]),
),
# Part labels
re_path(
r'^part/',
path(
'part/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^print/',
r'print/?',
PartLabelPrint.as_view(),
name='api-part-label-print',
),
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': label.models.PartLabel},
name='api-part-label-metadata',
),
re_path(
r'^.*$', PartLabelDetail.as_view(), name='api-part-label-detail'
),
path('', PartLabelDetail.as_view(), name='api-part-label-detail'),
]),
),
# List view
re_path(r'^.*$', PartLabelList.as_view(), name='api-part-label-list'),
path('', PartLabelList.as_view(), name='api-part-label-list'),
]),
),
# BuildLine labels
re_path(
r'^buildline/',
path(
'buildline/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^print/',
r'print/?',
BuildLineLabelPrint.as_view(),
name='api-buildline-label-print',
),
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': label.models.BuildLineLabel},
name='api-buildline-label-metadata',
),
re_path(
r'^.*$',
path(
'',
BuildLineLabelDetail.as_view(),
name='api-buildline-label-detail',
),
]),
),
# List view
re_path(
r'^.*$', BuildLineLabelList.as_view(), name='api-buildline-label-list'
),
path('', BuildLineLabelList.as_view(), name='api-buildline-label-list'),
]),
),
]

View File

@ -1491,20 +1491,20 @@ class OrderCalendarExport(ICalFeed):
order_api_urls = [
# API endpoints for purchase orders
re_path(
r'^po/',
path(
'po/',
include([
# Purchase order attachments
re_path(
r'attachment/',
path(
'attachment/',
include([
path(
'<int:pk>/',
PurchaseOrderAttachmentDetail.as_view(),
name='api-po-attachment-detail',
),
re_path(
r'^.*$',
path(
'',
PurchaseOrderAttachmentList.as_view(),
name='api-po-attachment-list',
),
@ -1512,87 +1512,81 @@ order_api_urls = [
),
# Individual purchase order detail URLs
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^cancel/', PurchaseOrderCancel.as_view(), name='api-po-cancel'
path(
'cancel/', PurchaseOrderCancel.as_view(), name='api-po-cancel'
),
re_path(
r'^complete/',
path(
'complete/',
PurchaseOrderComplete.as_view(),
name='api-po-complete',
),
re_path(
r'^issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'
),
re_path(
r'^metadata/',
path('issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'),
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrder},
name='api-po-metadata',
),
re_path(
r'^receive/',
path(
'receive/',
PurchaseOrderReceive.as_view(),
name='api-po-receive',
),
# PurchaseOrder detail API endpoint
re_path(
r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'
),
path('', PurchaseOrderDetail.as_view(), name='api-po-detail'),
]),
),
# Purchase order status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: PurchaseOrderStatus},
name='api-po-status-codes',
),
# Purchase order list
re_path(r'^.*$', PurchaseOrderList.as_view(), name='api-po-list'),
path('', PurchaseOrderList.as_view(), name='api-po-list'),
]),
),
# API endpoints for purchase order line items
re_path(
r'^po-line/',
path(
'po-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrderLineItem},
name='api-po-line-metadata',
),
re_path(
r'^.*$',
path(
'',
PurchaseOrderLineItemDetail.as_view(),
name='api-po-line-detail',
),
]),
),
re_path(
r'^.*$', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'
),
path('', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'),
]),
),
# API endpoints for purchase order extra line
re_path(
r'^po-extra-line/',
path(
'po-extra-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrderExtraLine},
name='api-po-extra-line-metadata',
),
re_path(
r'^.*$',
path(
'',
PurchaseOrderExtraLineDetail.as_view(),
name='api-po-extra-line-detail',
),
@ -1604,50 +1598,50 @@ order_api_urls = [
]),
),
# API endpoints for sales ordesr
re_path(
r'^so/',
path(
'so/',
include([
re_path(
r'attachment/',
path(
'attachment/',
include([
path(
'<int:pk>/',
SalesOrderAttachmentDetail.as_view(),
name='api-so-attachment-detail',
),
re_path(
r'^.*$',
path(
'',
SalesOrderAttachmentList.as_view(),
name='api-so-attachment-list',
),
]),
),
re_path(
r'^shipment/',
path(
'shipment/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
path(
'ship/',
SalesOrderShipmentComplete.as_view(),
name='api-so-shipment-ship',
),
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderShipment},
name='api-so-shipment-metadata',
),
re_path(
r'^.*$',
path(
'',
SalesOrderShipmentDetail.as_view(),
name='api-so-shipment-detail',
),
]),
),
re_path(
r'^.*$',
path(
'',
SalesOrderShipmentList.as_view(),
name='api-so-shipment-list',
),
@ -1655,63 +1649,61 @@ order_api_urls = [
),
# Sales order detail view
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^allocate/',
path(
'allocate/',
SalesOrderAllocate.as_view(),
name='api-so-allocate',
),
re_path(
r'^allocate-serials/',
path(
'allocate-serials/',
SalesOrderAllocateSerials.as_view(),
name='api-so-allocate-serials',
),
re_path(
r'^cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'
),
re_path(r'^issue/', SalesOrderIssue.as_view(), name='api-so-issue'),
re_path(
r'^complete/',
path('cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'),
path('issue/', SalesOrderIssue.as_view(), name='api-so-issue'),
path(
'complete/',
SalesOrderComplete.as_view(),
name='api-so-complete',
),
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrder},
name='api-so-metadata',
),
# SalesOrder detail endpoint
re_path(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'),
path('', SalesOrderDetail.as_view(), name='api-so-detail'),
]),
),
# Sales order status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: SalesOrderStatus},
name='api-so-status-codes',
),
# Sales order list view
re_path(r'^.*$', SalesOrderList.as_view(), name='api-so-list'),
path('', SalesOrderList.as_view(), name='api-so-list'),
]),
),
# API endpoints for sales order line items
re_path(
r'^so-line/',
path(
'so-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderLineItem},
name='api-so-line-metadata',
),
re_path(
r'^.*$',
path(
'',
SalesOrderLineItemDetail.as_view(),
name='api-so-line-detail',
),
@ -1721,20 +1713,20 @@ order_api_urls = [
]),
),
# API endpoints for sales order extra line
re_path(
r'^so-extra-line/',
path(
'so-extra-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderExtraLine},
name='api-so-extra-line-metadata',
),
re_path(
r'^.*$',
path(
'',
SalesOrderExtraLineDetail.as_view(),
name='api-so-extra-line-detail',
),
@ -1744,35 +1736,31 @@ order_api_urls = [
]),
),
# API endpoints for sales order allocations
re_path(
r'^so-allocation/',
path(
'so-allocation/',
include([
path(
'<int:pk>/',
SalesOrderAllocationDetail.as_view(),
name='api-so-allocation-detail',
),
re_path(
r'^.*$',
SalesOrderAllocationList.as_view(),
name='api-so-allocation-list',
),
path('', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'),
]),
),
# API endpoints for return orders
re_path(
r'^ro/',
path(
'ro/',
include([
re_path(
r'^attachment/',
path(
'attachment/',
include([
path(
'<int:pk>/',
ReturnOrderAttachmentDetail.as_view(),
name='api-return-order-attachment-detail',
),
re_path(
r'^.*$',
path(
'',
ReturnOrderAttachmentList.as_view(),
name='api-return-order-attachment-list',
),
@ -1782,73 +1770,71 @@ order_api_urls = [
path(
'<int:pk>/',
include([
re_path(
r'cancel/',
path(
'cancel/',
ReturnOrderCancel.as_view(),
name='api-return-order-cancel',
),
re_path(
r'complete/',
path(
'complete/',
ReturnOrderComplete.as_view(),
name='api-return-order-complete',
),
re_path(
r'issue/',
path(
'issue/',
ReturnOrderIssue.as_view(),
name='api-return-order-issue',
),
re_path(
r'receive/',
path(
'receive/',
ReturnOrderReceive.as_view(),
name='api-return-order-receive',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrder},
name='api-return-order-metadata',
),
re_path(
r'.*$',
ReturnOrderDetail.as_view(),
name='api-return-order-detail',
path(
'', ReturnOrderDetail.as_view(), name='api-return-order-detail'
),
]),
),
# Return order status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: ReturnOrderStatus},
name='api-return-order-status-codes',
),
# Return Order list
re_path(r'^.*$', ReturnOrderList.as_view(), name='api-return-order-list'),
path('', ReturnOrderList.as_view(), name='api-return-order-list'),
]),
),
# API endpoints for return order lines
re_path(
r'^ro-line/',
path(
'ro-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrderLineItem},
name='api-return-order-line-metadata',
),
re_path(
r'^.*$',
path(
'',
ReturnOrderLineItemDetail.as_view(),
name='api-return-order-line-detail',
),
]),
),
# Return order line item status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: ReturnOrderLineStatus},
name='api-return-order-line-status-codes',
@ -1859,20 +1845,20 @@ order_api_urls = [
]),
),
# API endpoints for return order extra line
re_path(
r'^ro-extra-line/',
path(
'ro-extra-line/',
include([
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrderExtraLine},
name='api-return-order-extra-line-metadata',
),
re_path(
r'^.*$',
path(
'',
ReturnOrderExtraLineDetail.as_view(),
name='api-return-order-extra-line-detail',
),

View File

@ -5,46 +5,46 @@ Provides URL endpoints for:
- Detail view of Purchase Orders
"""
from django.urls import include, path, re_path
from django.urls import include, path
from . import views
purchase_order_detail_urls = [
re_path(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'),
re_path(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'),
re_path(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'),
path('upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'),
path('export/', views.PurchaseOrderExport.as_view(), name='po-export'),
path('', views.PurchaseOrderDetail.as_view(), name='po-detail'),
]
purchase_order_urls = [
re_path(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'),
path('pricing/', views.LineItemPricing.as_view(), name='line-pricing'),
# Display detail view for a single purchase order
path(r'<int:pk>/', include(purchase_order_detail_urls)),
path('<int:pk>/', include(purchase_order_detail_urls)),
# Display complete list of purchase orders
re_path(r'^.*$', views.PurchaseOrderIndex.as_view(), name='purchase-order-index'),
path('', views.PurchaseOrderIndex.as_view(), name='purchase-order-index'),
]
sales_order_detail_urls = [
re_path(r'^export/', views.SalesOrderExport.as_view(), name='so-export'),
re_path(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),
path('export/', views.SalesOrderExport.as_view(), name='so-export'),
path('', views.SalesOrderDetail.as_view(), name='so-detail'),
]
sales_order_urls = [
# Display detail view for a single SalesOrder
path(r'<int:pk>/', include(sales_order_detail_urls)),
path('<int:pk>/', include(sales_order_detail_urls)),
# Display list of all sales orders
re_path(r'^.*$', views.SalesOrderIndex.as_view(), name='sales-order-index'),
path('', views.SalesOrderIndex.as_view(), name='sales-order-index'),
]
return_order_urls = [
path(r'<int:pk>/', views.ReturnOrderDetail.as_view(), name='return-order-detail'),
path('<int:pk>/', views.ReturnOrderDetail.as_view(), name='return-order-detail'),
# Display list of all return orders
re_path(r'^.*$', views.ReturnOrderIndex.as_view(), name='return-order-index'),
path('', views.ReturnOrderIndex.as_view(), name='return-order-index'),
]
order_urls = [
re_path(r'^purchase-order/', include(purchase_order_urls)),
re_path(r'^sales-order/', include(sales_order_urls)),
re_path(r'^return-order/', include(return_order_urls)),
path('purchase-order/', include(purchase_order_urls)),
path('sales-order/', include(sales_order_urls)),
path('return-order/', include(return_order_urls)),
]

View File

@ -1954,31 +1954,31 @@ class BomItemSubstituteDetail(RetrieveUpdateDestroyAPI):
part_api_urls = [
# Base URL for PartCategory API endpoints
re_path(
r'^category/',
path(
'category/',
include([
re_path(r'^tree/', CategoryTree.as_view(), name='api-part-category-tree'),
re_path(
r'^parameters/',
path('tree/', CategoryTree.as_view(), name='api-part-category-tree'),
path(
'parameters/',
include([
re_path(
r'^(?P<pk>\d+)/',
path(
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartCategoryParameterTemplate},
name='api-part-category-parameter-metadata',
),
re_path(
r'^.*$',
path(
'',
CategoryParameterDetail.as_view(),
name='api-part-category-parameter-detail',
),
]),
),
re_path(
r'^.*$',
path(
'',
CategoryParameterList.as_view(),
name='api-part-category-parameter-list',
),
@ -1986,40 +1986,36 @@ part_api_urls = [
),
# Category detail endpoints
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartCategory},
name='api-part-category-metadata',
),
# PartCategory detail endpoint
re_path(
r'^.*$',
CategoryDetail.as_view(),
name='api-part-category-detail',
),
path('', CategoryDetail.as_view(), name='api-part-category-detail'),
]),
),
path('', CategoryList.as_view(), name='api-part-category-list'),
]),
),
# Base URL for PartTestTemplate API endpoints
re_path(
r'^test-template/',
path(
'test-template/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartTestTemplate},
name='api-part-test-template-metadata',
),
re_path(
r'^.*$',
path(
'',
PartTestTemplateDetail.as_view(),
name='api-part-test-template-detail',
),
@ -2031,11 +2027,11 @@ part_api_urls = [
]),
),
# Base URL for PartAttachment API endpoints
re_path(
r'^attachment/',
path(
'attachment/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
PartAttachmentDetail.as_view(),
name='api-part-attachment-detail',
),
@ -2043,112 +2039,104 @@ part_api_urls = [
]),
),
# Base URL for part sale pricing
re_path(
r'^sale-price/',
path(
'sale-price/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
PartSalePriceDetail.as_view(),
name='api-part-sale-price-detail',
),
re_path(
r'^.*$', PartSalePriceList.as_view(), name='api-part-sale-price-list'
),
path('', PartSalePriceList.as_view(), name='api-part-sale-price-list'),
]),
),
# Base URL for part internal pricing
re_path(
r'^internal-price/',
path(
'internal-price/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
PartInternalPriceDetail.as_view(),
name='api-part-internal-price-detail',
),
re_path(
r'^.*$',
PartInternalPriceList.as_view(),
name='api-part-internal-price-list',
path(
'', PartInternalPriceList.as_view(), name='api-part-internal-price-list'
),
]),
),
# Base URL for PartRelated API endpoints
re_path(
r'^related/',
path(
'related/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartRelated},
name='api-part-related-metadata',
),
re_path(
r'^.*$',
PartRelatedDetail.as_view(),
name='api-part-related-detail',
path(
'', PartRelatedDetail.as_view(), name='api-part-related-detail'
),
]),
),
re_path(r'^.*$', PartRelatedList.as_view(), name='api-part-related-list'),
path('', PartRelatedList.as_view(), name='api-part-related-list'),
]),
),
# Base URL for PartParameter API endpoints
re_path(
r'^parameter/',
path(
'parameter/',
include([
path(
'template/',
include([
re_path(
r'^(?P<pk>\d+)/',
path(
'<int:pk>/',
include([
re_path(
r'^metadata/?',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartParameterTemplate},
name='api-part-parameter-template-metadata',
),
re_path(
r'^.*$',
path(
'',
PartParameterTemplateDetail.as_view(),
name='api-part-parameter-template-detail',
),
]),
),
re_path(
r'^.*$',
path(
'',
PartParameterTemplateList.as_view(),
name='api-part-parameter-template-list',
),
]),
),
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/?',
path(
'metadata/',
MetadataView.as_view(),
{'model': PartParameter},
name='api-part-parameter-metadata',
),
re_path(
r'^.*$',
path(
'',
PartParameterDetail.as_view(),
name='api-part-parameter-detail',
),
]),
),
re_path(
r'^.*$', PartParameterList.as_view(), name='api-part-parameter-list'
),
path('', PartParameterList.as_view(), name='api-part-parameter-list'),
]),
),
# Part stocktake data
re_path(
r'^stocktake/',
path(
'stocktake/',
include([
path(
r'report/',
@ -2158,25 +2146,23 @@ part_api_urls = [
PartStocktakeReportGenerate.as_view(),
name='api-part-stocktake-report-generate',
),
re_path(
r'^.*$',
path(
'',
PartStocktakeReportList.as_view(),
name='api-part-stocktake-report-list',
),
]),
),
path(
r'<int:pk>/',
'<int:pk>/',
PartStocktakeDetail.as_view(),
name='api-part-stocktake-detail',
),
re_path(
r'^.*$', PartStocktakeList.as_view(), name='api-part-stocktake-list'
),
path('', PartStocktakeList.as_view(), name='api-part-stocktake-list'),
]),
),
re_path(
r'^thumbs/',
path(
'thumbs/',
include([
path('', PartThumbs.as_view(), name='api-part-thumbs'),
re_path(
@ -2187,117 +2173,101 @@ part_api_urls = [
]),
),
# BOM template
re_path(
r'^bom_template/?',
path(
'bom_template/',
views.BomUploadTemplate.as_view(),
name='api-bom-upload-template',
),
path(
r'<int:pk>/',
'<int:pk>/',
include([
# Endpoint for extra serial number information
re_path(
r'^serial-numbers/',
path(
'serial-numbers/',
PartSerialNumberDetail.as_view(),
name='api-part-serial-number-detail',
),
# Endpoint for future scheduling information
re_path(
r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'
),
re_path(
r'^requirements/',
path('scheduling/', PartScheduling.as_view(), name='api-part-scheduling'),
path(
'requirements/',
PartRequirements.as_view(),
name='api-part-requirements',
),
# Endpoint for duplicating a BOM for the specific Part
re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
path('bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
# Endpoint for validating a BOM for the specific Part
re_path(
r'^bom-validate/',
PartValidateBOM.as_view(),
name='api-part-bom-validate',
path(
'bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'
),
# Part metadata
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': Part},
name='api-part-metadata',
),
# Part pricing
re_path(r'^pricing/', PartPricingDetail.as_view(), name='api-part-pricing'),
path('pricing/', PartPricingDetail.as_view(), name='api-part-pricing'),
# BOM download
re_path(
r'^bom-download/?', views.BomDownload.as_view(), name='api-bom-download'
),
path('bom-download/', views.BomDownload.as_view(), name='api-bom-download'),
# Old pricing endpoint
re_path(r'^pricing2/', views.PartPricing.as_view(), name='part-pricing'),
path('pricing2/', views.PartPricing.as_view(), name='part-pricing'),
# Part detail endpoint
re_path(r'^.*$', PartDetail.as_view(), name='api-part-detail'),
path('', PartDetail.as_view(), name='api-part-detail'),
]),
),
re_path(
r'^change_category/',
path(
'change_category/',
PartChangeCategory.as_view(),
name='api-part-change-category',
),
re_path(r'^.*$', PartList.as_view(), name='api-part-list'),
path('', PartList.as_view(), name='api-part-list'),
]
bom_api_urls = [
re_path(
r'^substitute/',
path(
'substitute/',
include([
# Detail view
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/?',
path(
'metadata/',
MetadataView.as_view(),
{'model': BomItemSubstitute},
name='api-bom-substitute-metadata',
),
re_path(
r'^.*$',
path(
'',
BomItemSubstituteDetail.as_view(),
name='api-bom-substitute-detail',
),
]),
),
# Catch all
re_path(
r'^.*$', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'
),
path('', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'),
]),
),
# BOM Item Detail
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'
),
re_path(
r'^metadata/?',
path('validate/', BomItemValidate.as_view(), name='api-bom-item-validate'),
path(
'metadata/',
MetadataView.as_view(),
{'model': BomItem},
name='api-bom-item-metadata',
),
re_path(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'),
path('', BomDetail.as_view(), name='api-bom-item-detail'),
]),
),
# API endpoint URLs for importing BOM data
re_path(
r'^import/upload/', BomImportUpload.as_view(), name='api-bom-import-upload'
),
re_path(
r'^import/extract/', BomImportExtract.as_view(), name='api-bom-import-extract'
),
re_path(
r'^import/submit/', BomImportSubmit.as_view(), name='api-bom-import-submit'
),
path('import/upload/', BomImportUpload.as_view(), name='api-bom-import-upload'),
path('import/extract/', BomImportExtract.as_view(), name='api-bom-import-extract'),
path('import/submit/', BomImportSubmit.as_view(), name='api-bom-import-submit'),
# Catch-all
re_path(r'^.*$', BomList.as_view(), name='api-bom-list'),
path('', BomList.as_view(), name='api-bom-list'),
]

View File

@ -12,13 +12,11 @@ from django.urls import include, path, re_path
from . import views
part_detail_urls = [
re_path(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
path('bom-upload/', views.BomUpload.as_view(), name='upload-bom'),
# Normal thumbnail with form
re_path(
r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'
),
path('thumb-select/', views.PartImageSelect.as_view(), name='part-image-select'),
# Any other URLs go to the part detail page
re_path(r'^.*$', views.PartDetail.as_view(), name='part-detail'),
path('', views.PartDetail.as_view(), name='part-detail'),
]
category_urls = [
@ -29,15 +27,15 @@ category_urls = [
# URL list for part web interface
part_urls = [
# Upload a part
re_path(r'^import/$', views.PartImport.as_view(), name='part-import'),
path('import/', views.PartImport.as_view(), name='part-import'),
re_path(
r'^import/?', views.PartImportTemplate.as_view(), name='part-template-download'
),
re_path(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'),
path('import-api/', views.PartImportAjax.as_view(), name='api-part-import'),
# Individual part using pk
path(r'<int:pk>/', include(part_detail_urls)),
path('<int:pk>/', include(part_detail_urls)),
# Part category
re_path(r'^category/', include(category_urls)),
path('category/', include(category_urls)),
# Individual part using IPN as slug
re_path(
r'^(?P<slug>[-\w]+)/',
@ -45,5 +43,5 @@ part_urls = [
name='part-detail-from-ipn',
),
# Top level part list (display top level parts and categories)
re_path(r'^.*$', views.PartIndex.as_view(), name='part-index'),
path('', views.PartIndex.as_view(), name='part-index'),
]

View File

@ -354,76 +354,72 @@ class RegistryStatusView(APIView):
plugin_api_urls = [
re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'),
re_path(r'^barcode/', include(barcode_api_urls)),
re_path(r'^locate/', LocatePluginView.as_view(), name='api-locate-plugin'),
re_path(
r'^plugins/',
path('action/', ActionPluginView.as_view(), name='api-action-plugin'),
path('barcode/', include(barcode_api_urls)),
path('locate/', LocatePluginView.as_view(), name='api-locate-plugin'),
path(
'plugins/',
include([
# Plugin settings URLs
re_path(
r'^settings/',
path(
'settings/',
include([
re_path(
r'^(?P<plugin>[-\w]+)/(?P<key>\w+)/',
PluginSettingDetail.as_view(),
name='api-plugin-setting-detail',
), # Used for admin interface
re_path(
r'^.*$',
PluginSettingList.as_view(),
name='api-plugin-setting-list',
path(
'', PluginSettingList.as_view(), name='api-plugin-setting-list'
),
]),
),
# Detail views for a single PluginConfig item
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^settings/',
path(
'settings/',
include([
re_path(
r'^(?P<key>\w+)/',
PluginSettingDetail.as_view(),
name='api-plugin-setting-detail-pk',
),
re_path(
r'^.*$',
path(
'',
PluginAllSettingList.as_view(),
name='api-plugin-settings',
),
]),
),
re_path(
r'^activate/',
path(
'activate/',
PluginActivate.as_view(),
name='api-plugin-detail-activate',
),
re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
path('', PluginDetail.as_view(), name='api-plugin-detail'),
]),
),
# Metadata
re_path(
'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PluginConfig},
name='api-plugin-metadata',
),
# Plugin management
re_path(r'^reload/', PluginReload.as_view(), name='api-plugin-reload'),
re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
re_path(
r'^activate/', PluginActivate.as_view(), name='api-plugin-activate'
),
path('reload/', PluginReload.as_view(), name='api-plugin-reload'),
path('install/', PluginInstall.as_view(), name='api-plugin-install'),
path('activate/', PluginActivate.as_view(), name='api-plugin-activate'),
# Registry status
re_path(
r'^status/',
path(
'status/',
RegistryStatusView.as_view(),
name='api-plugin-registry-status',
),
# Anything else
re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
path('', PluginList.as_view(), name='api-plugin-list'),
]),
),
]

View File

@ -3,7 +3,7 @@
import logging
from django.db.models import F
from django.urls import path, re_path
from django.urls import path
from django.utils.translation import gettext_lazy as _
from rest_framework import permissions
@ -578,5 +578,5 @@ barcode_api_urls = [
# Allocate stock to a sales order by scanning barcode
path('so-allocate/', BarcodeSOAllocate.as_view(), name='api-barcode-so-allocate'),
# Catch-all performs barcode 'scan'
re_path(r'^.*$', BarcodeScan.as_view(), name='api-barcode-scan'),
path('', BarcodeScan.as_view(), name='api-barcode-scan'),
]

View File

@ -4,7 +4,7 @@ import os
from django.conf import settings
from django.test import TestCase
from django.urls import include, re_path, reverse
from django.urls import include, path, re_path, reverse
from error_report.models import Error
@ -96,7 +96,7 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase):
def test():
return 'ccc'
URLS = [re_path('testpath', test, name='test')]
URLS = [path('testpath', test, name='test')]
self.mixin = UrlsCls()

View File

@ -4,7 +4,7 @@ import json
from django.core.exceptions import ValidationError
from django.http import HttpResponse
from django.urls import include, re_path
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
from plugin import InvenTreePlugin
@ -38,13 +38,13 @@ class SampleIntegrationPlugin(
def setup_urls(self):
"""Urls that are exposed by this plugin."""
he_urls = [
re_path(r'^he/', self.view_test, name='he'),
re_path(r'^ha/', self.view_test, name='ha'),
path('he/', self.view_test, name='he'),
path('ha/', self.view_test, name='ha'),
]
return [
re_path(r'^hi/', self.view_test, name='hi'),
re_path(r'^ho/', include(he_urls), name='ho'),
path('hi/', self.view_test, name='hi'),
path('ho/', include(he_urls), name='ho'),
]
SETTINGS = {

View File

@ -513,20 +513,20 @@ class StockLocationReportPrint(StockLocationReportMixin, ReportPrintMixin, Retri
report_api_urls = [
# Purchase order reports
re_path(
r'po/',
path(
'po/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/',
r'print/?',
PurchaseOrderReportPrint.as_view(),
name='api-po-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': PurchaseOrderReport},
name='api-po-report-metadata',
@ -543,20 +543,20 @@ report_api_urls = [
]),
),
# Sales order reports
re_path(
r'so/',
path(
'so/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/',
r'print/?',
SalesOrderReportPrint.as_view(),
name='api-so-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': SalesOrderReport},
name='api-so-report-metadata',
@ -572,19 +572,19 @@ report_api_urls = [
]),
),
# Return order reports
re_path(
r'ro/',
path(
'ro/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
path(
r'print/',
ReturnOrderReportPrint.as_view(),
name='api-return-order-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': ReturnOrderReport},
name='api-so-report-metadata',
@ -602,126 +602,122 @@ report_api_urls = [
]),
),
# Build reports
re_path(
r'build/',
path(
'build/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
BuildReportPrint.as_view(),
name='api-build-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': BuildReport},
name='api-build-report-metadata',
),
re_path(
r'^.*$',
BuildReportDetail.as_view(),
name='api-build-report-detail',
path(
'', BuildReportDetail.as_view(), name='api-build-report-detail'
),
]),
),
# List view
re_path(r'^.*$', BuildReportList.as_view(), name='api-build-report-list'),
path('', BuildReportList.as_view(), name='api-build-report-list'),
]),
),
# Bill of Material reports
re_path(
r'bom/',
path(
'bom/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
BOMReportPrint.as_view(),
name='api-bom-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': BillOfMaterialsReport},
name='api-bom-report-metadata',
),
re_path(
r'^.*$', BOMReportDetail.as_view(), name='api-bom-report-detail'
),
path('', BOMReportDetail.as_view(), name='api-bom-report-detail'),
]),
),
# List view
re_path(r'^.*$', BOMReportList.as_view(), name='api-bom-report-list'),
path('', BOMReportList.as_view(), name='api-bom-report-list'),
]),
),
# Stock item test reports
re_path(
r'test/',
path(
'test/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
StockItemTestReportPrint.as_view(),
name='api-stockitem-testreport-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'report': TestReport},
name='api-stockitem-testreport-metadata',
),
re_path(
r'^.*$',
path(
'',
StockItemTestReportDetail.as_view(),
name='api-stockitem-testreport-detail',
),
]),
),
# List view
re_path(
r'^.*$',
path(
'',
StockItemTestReportList.as_view(),
name='api-stockitem-testreport-list',
),
]),
),
# Stock Location reports (Stock Location Reports -> sir)
re_path(
r'slr/',
path(
'slr/',
include([
# Detail views
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'print/?',
StockLocationReportPrint.as_view(),
name='api-stocklocation-report-print',
),
re_path(
r'metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'report': StockLocationReport},
name='api-stocklocation-report-metadata',
),
re_path(
r'^.*$',
path(
'',
StockLocationReportDetail.as_view(),
name='api-stocklocation-report-detail',
),
]),
),
# List view
re_path(
r'^.*$',
path(
'',
StockLocationReportList.as_view(),
name='api-stocklocation-report-list',
),

View File

@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError
from django.db import transaction
from django.db.models import F, Q
from django.http import JsonResponse
from django.urls import include, path, re_path
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as rest_filters
@ -1485,69 +1485,63 @@ class LocationDetail(CustomRetrieveUpdateDestroyAPI):
stock_api_urls = [
re_path(
r'^location/',
path(
'location/',
include([
re_path(r'^tree/', StockLocationTree.as_view(), name='api-location-tree'),
path('tree/', StockLocationTree.as_view(), name='api-location-tree'),
# Stock location detail endpoints
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': StockLocation},
name='api-location-metadata',
),
re_path(
r'^.*$', LocationDetail.as_view(), name='api-location-detail'
),
path('', LocationDetail.as_view(), name='api-location-detail'),
]),
),
re_path(r'^.*$', StockLocationList.as_view(), name='api-location-list'),
path('', StockLocationList.as_view(), name='api-location-list'),
]),
),
# Stock location type endpoints
re_path(
r'^location-type/',
path(
'location-type/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': StockLocationType},
name='api-location-type-metadata',
),
re_path(
r'^.*$',
path(
'',
StockLocationTypeDetail.as_view(),
name='api-location-type-detail',
),
]),
),
re_path(
r'^.*$', StockLocationTypeList.as_view(), name='api-location-type-list'
),
path('', StockLocationTypeList.as_view(), name='api-location-type-list'),
]),
),
# Endpoints for bulk stock adjustment actions
re_path(r'^count/', StockCount.as_view(), name='api-stock-count'),
re_path(r'^add/', StockAdd.as_view(), name='api-stock-add'),
re_path(r'^remove/', StockRemove.as_view(), name='api-stock-remove'),
re_path(r'^transfer/', StockTransfer.as_view(), name='api-stock-transfer'),
re_path(r'^assign/', StockAssign.as_view(), name='api-stock-assign'),
re_path(r'^merge/', StockMerge.as_view(), name='api-stock-merge'),
re_path(
r'^change_status/', StockChangeStatus.as_view(), name='api-stock-change-status'
),
path('count/', StockCount.as_view(), name='api-stock-count'),
path('add/', StockAdd.as_view(), name='api-stock-add'),
path('remove/', StockRemove.as_view(), name='api-stock-remove'),
path('transfer/', StockTransfer.as_view(), name='api-stock-transfer'),
path('assign/', StockAssign.as_view(), name='api-stock-assign'),
path('merge/', StockMerge.as_view(), name='api-stock-merge'),
path('change_status/', StockChangeStatus.as_view(), name='api-stock-change-status'),
# StockItemAttachment API endpoints
re_path(
r'^attachment/',
path(
'attachment/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
StockAttachmentDetail.as_view(),
name='api-stock-attachment-detail',
),
@ -1555,92 +1549,82 @@ stock_api_urls = [
]),
),
# StockItemTestResult API endpoints
re_path(
r'^test/',
path(
'test/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^metadata/',
path(
'metadata/',
MetadataView.as_view(),
{'model': StockItemTestResult},
name='api-stock-test-result-metadata',
),
re_path(
r'^.*$',
path(
'',
StockItemTestResultDetail.as_view(),
name='api-stock-test-result-detail',
),
]),
),
re_path(
r'^.*$',
StockItemTestResultList.as_view(),
name='api-stock-test-result-list',
path(
'', StockItemTestResultList.as_view(), name='api-stock-test-result-list'
),
]),
),
# StockItemTracking API endpoints
re_path(
r'^track/',
path(
'track/',
include([
path(
r'<int:pk>/',
'<int:pk>/',
StockTrackingDetail.as_view(),
name='api-stock-tracking-detail',
),
# Stock tracking status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: StockHistoryCode},
name='api-stock-tracking-status-codes',
),
re_path(
r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'
),
path('', StockTrackingList.as_view(), name='api-stock-tracking-list'),
]),
),
# Detail views for a single stock item
path(
r'<int:pk>/',
'<int:pk>/',
include([
re_path(
r'^convert/', StockItemConvert.as_view(), name='api-stock-item-convert'
),
re_path(
r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'
),
re_path(
r'^metadata/',
path('convert/', StockItemConvert.as_view(), name='api-stock-item-convert'),
path('install/', StockItemInstall.as_view(), name='api-stock-item-install'),
path(
'metadata/',
MetadataView.as_view(),
{'model': StockItem},
name='api-stock-item-metadata',
),
re_path(
r'^return/', StockItemReturn.as_view(), name='api-stock-item-return'
),
re_path(
r'^serialize/',
path('return/', StockItemReturn.as_view(), name='api-stock-item-return'),
path(
'serialize/',
StockItemSerialize.as_view(),
name='api-stock-item-serialize',
),
re_path(
r'^uninstall/',
path(
'uninstall/',
StockItemUninstall.as_view(),
name='api-stock-item-uninstall',
),
re_path(r'^.*$', StockDetail.as_view(), name='api-stock-detail'),
path('', StockDetail.as_view(), name='api-stock-detail'),
]),
),
# Stock item status code information
re_path(
r'status/',
path(
'status/',
StatusView.as_view(),
{StatusView.MODEL_REF: StockStatus},
name='api-stock-status-codes',
),
# Anything else
re_path(r'^.*$', StockList.as_view(), name='api-stock-list'),
path('', StockList.as_view(), name='api-stock-list'),
]

View File

@ -1,33 +1,29 @@
"""URL lookup for Stock app."""
from django.urls import include, path, re_path
from django.urls import include, path
from stock import views
location_urls = [
path(
r'<int:pk>/',
'<int:pk>/',
include([
# Anything else - direct to the location detail view
re_path(
'^.*$',
views.StockLocationDetail.as_view(),
name='stock-location-detail',
)
path('', views.StockLocationDetail.as_view(), name='stock-location-detail')
]),
)
]
stock_item_detail_urls = [
# Anything else - direct to the item detail view
re_path('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail')
path('', views.StockItemDetail.as_view(), name='stock-item-detail')
]
stock_urls = [
# Stock location
re_path(r'^location/', include(location_urls)),
path('location/', include(location_urls)),
# Individual stock items
re_path(r'^item/(?P<pk>\d+)/', include(stock_item_detail_urls)),
path('item/<int:pk>/', include(stock_item_detail_urls)),
# Default to the stock index page
re_path(r'^.*$', views.StockIndex.as_view(), name='stock-index'),
path('', views.StockIndex.as_view(), name='stock-index'),
]

View File

@ -249,23 +249,23 @@ class GetAuthToken(APIView):
user_urls = [
re_path(r'roles/?$', RoleDetails.as_view(), name='api-user-roles'),
re_path(r'token/?$', GetAuthToken.as_view(), name='api-token'),
re_path(r'^me/', MeUserDetail.as_view(), name='api-user-me'),
re_path(
r'^owner/',
path('roles/', RoleDetails.as_view(), name='api-user-roles'),
path('token/', GetAuthToken.as_view(), name='api-token'),
path('me/', MeUserDetail.as_view(), name='api-user-me'),
path(
'owner/',
include([
path('<int:pk>/', OwnerDetail.as_view(), name='api-owner-detail'),
re_path(r'^.*$', OwnerList.as_view(), name='api-owner-list'),
path('', OwnerList.as_view(), name='api-owner-list'),
]),
),
re_path(
r'^group/',
path(
'group/',
include([
re_path(
r'^(?P<pk>[0-9]+)/?$', GroupDetail.as_view(), name='api-group-detail'
),
re_path(r'^.*$', GroupList.as_view(), name='api-group-list'),
path('', GroupList.as_view(), name='api-group-list'),
]),
),
re_path(r'^(?P<pk>[0-9]+)/?$', UserDetail.as_view(), name='api-user-detail'),

View File

@ -2,7 +2,7 @@
from django.conf import settings
from django.shortcuts import redirect
from django.urls import include, path, re_path
from django.urls import include, path
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import TemplateView
@ -31,7 +31,7 @@ urlpatterns = [
spa_view,
name='password_reset_confirm',
),
re_path('.*', spa_view),
path('', spa_view),
]),
),
assets_path,

View File

@ -39,7 +39,7 @@ def view_test(self, request):
def setup_urls(self):
return [
re_path(r'^test/', self.view_test, name='test')
path('test/', self.view_test, name='test')
]
```