From d05472b30ca43d3217faacf962125bffc1192318 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 21:53:12 +0200 Subject: [PATCH 1/6] upgrade to pyhton 3.9 syntax using pyupgrade --- InvenTree/InvenTree/forms.py | 2 +- InvenTree/InvenTree/helpers.py | 2 +- InvenTree/InvenTree/middleware.py | 2 +- InvenTree/InvenTree/tests.py | 3 +-- InvenTree/build/models.py | 2 +- InvenTree/common/test_tasks.py | 1 - InvenTree/order/migrations/0058_auto_20211126_1210.py | 2 +- InvenTree/order/models.py | 8 ++++---- InvenTree/part/models.py | 2 +- InvenTree/stock/migrations/0061_auto_20210511_0911.py | 6 +++--- ci/check_version_number.py | 4 ++-- 11 files changed, 16 insertions(+), 18 deletions(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 91863f04e2..dd40e54d9c 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -319,7 +319,7 @@ class CustomSocialAccountAdapter(RegistratonMixin, DefaultSocialAccountAdapter): redirect_url = reverse('two-factor-authenticate') # Add GET parameters to the URL if they exist. if request.GET: - redirect_url += u'?' + urlencode(request.GET) + redirect_url += '?' + urlencode(request.GET) raise ImmediateHttpResponse( response=HttpResponseRedirect(redirect_url) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 7bd4fd819d..1258fffe61 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -432,7 +432,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): next_number += 1 # Split input string by whitespace or comma (,) characters - groups = re.split("[\s,]+", serials) + groups = re.split(r"[\s,]+", serials) numbers = [] errors = [] diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index b43720b8bc..0ec1d4e6c5 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -85,7 +85,7 @@ class AuthRequiredMiddleware(object): if path not in urls and not path.startswith('/api/'): # Save the 'next' parameter to pass through to the login view - return redirect('%s?next=%s' % (reverse_lazy('account_login'), request.path)) + return redirect('{}?next={}'.format(reverse_lazy('account_login'), request.path)) response = self.get_response(request) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 13f9198d92..dc3aff85e6 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -1,4 +1,3 @@ - import json from test.support import EnvironmentVarGuard @@ -186,7 +185,7 @@ class TestDownloadFile(TestCase): def test_download(self): helpers.DownloadFile("hello world", "out.txt") - helpers.DownloadFile(bytes("hello world".encode("utf8")), "out.bin") + helpers.DownloadFile(bytes(b"hello world"), "out.bin") class TestMPTT(TestCase): diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 86bb256539..3edced5ffe 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -53,7 +53,7 @@ def get_next_build_number(): build = Build.objects.exclude(reference=None).last() - attempts = set([build.reference]) + attempts = {build.reference} reference = build.reference diff --git a/InvenTree/common/test_tasks.py b/InvenTree/common/test_tasks.py index 4a3da9c028..3f85316c41 100644 --- a/InvenTree/common/test_tasks.py +++ b/InvenTree/common/test_tasks.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- from django.test import TestCase diff --git a/InvenTree/order/migrations/0058_auto_20211126_1210.py b/InvenTree/order/migrations/0058_auto_20211126_1210.py index a1836ff380..6ba2430af9 100644 --- a/InvenTree/order/migrations/0058_auto_20211126_1210.py +++ b/InvenTree/order/migrations/0058_auto_20211126_1210.py @@ -33,7 +33,7 @@ def calculate_shipped_quantity(apps, schema_editor): part=item.part ) - q = sum([item.quantity for item in items]) + q = sum(item.quantity for item in items) item.shipped = q diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index c9147bac20..63862078f6 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -49,7 +49,7 @@ def get_next_po_number(): order = PurchaseOrder.objects.exclude(reference=None).last() - attempts = set([order.reference]) + attempts = {order.reference} reference = order.reference @@ -78,7 +78,7 @@ def get_next_so_number(): order = SalesOrder.objects.exclude(reference=None).last() - attempts = set([order.reference]) + attempts = {order.reference} reference = order.reference @@ -161,10 +161,10 @@ class Order(ReferenceIndexingMixin): # gather name reference price_ref = 'sale_price' if isinstance(self, SalesOrder) else 'purchase_price' # order items - total += sum([a.quantity * convert_money(getattr(a, price_ref), target_currency) for a in self.lines.all() if getattr(a, price_ref)]) + total += sum(a.quantity * convert_money(getattr(a, price_ref), target_currency) for a in self.lines.all() if getattr(a, price_ref)) # extra lines - total += sum([a.quantity * convert_money(a.price, target_currency) for a in self.extra_lines.all() if a.price]) + total += sum(a.quantity * convert_money(a.price, target_currency) for a in self.extra_lines.all() if a.price) # set decimal-places total.decimal_places = 4 diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 365ed62914..46b2154c43 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -2510,7 +2510,7 @@ def validate_template_name(name): Prevent illegal characters in "name" field for PartParameterTemplate """ - for c in "!@#$%^&*()<>{}[].,?/\|~`_+-=\'\"": + for c in "!@#$%^&*()<>{}[].,?/\\|~`_+-=\'\"": if c in str(name): raise ValidationError(_(f"Illegal character in template name ({c})")) diff --git a/InvenTree/stock/migrations/0061_auto_20210511_0911.py b/InvenTree/stock/migrations/0061_auto_20210511_0911.py index 8d7a398f04..1e20071d59 100644 --- a/InvenTree/stock/migrations/0061_auto_20210511_0911.py +++ b/InvenTree/stock/migrations/0061_auto_20210511_0911.py @@ -78,7 +78,7 @@ def update_history(apps, schema_editor): tracking_type = StockHistoryCode.STOCK_REMOVE # Extract the number of removed items - result = re.search("^removed ([\d\.]+) items", title) + result = re.search(r"^removed ([\d\.]+) items", title) if result: @@ -102,7 +102,7 @@ def update_history(apps, schema_editor): elif 'moved to' in title: tracking_type = StockHistoryCode.STOCK_MOVE - result = re.search('^Moved to (.*)( - )*(.*) \(from.*$', entry.title) + result = re.search(r'^Moved to (.*)( - )*(.*) \(from.*$', entry.title) if result: # Legacy tracking entries recorded the location in multiple ways, because.. why not? @@ -157,7 +157,7 @@ def update_history(apps, schema_editor): tracking_type = StockHistoryCode.STOCK_ADD # Extract the number of added items - result = re.search("^added ([\d\.]+) items", title) + result = re.search(r"^added ([\d\.]+) items", title) if result: diff --git a/ci/check_version_number.py b/ci/check_version_number.py index 258c8780d8..0514854407 100644 --- a/ci/check_version_number.py +++ b/ci/check_version_number.py @@ -66,7 +66,7 @@ if __name__ == '__main__': print("Checking development branch") - pattern = "^\d+(\.\d+)+ dev$" + pattern = r"^\d+(\.\d+)+ dev$" result = re.match(pattern, version) @@ -82,7 +82,7 @@ if __name__ == '__main__': print("Checking release branch") - pattern = "^\d+(\.\d+)+$" + pattern = r"^\d+(\.\d+)+$" result = re.match(pattern, version) From 67ab45bdeee56cca9398c2cceecb72473340b7e5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 22:00:18 +0200 Subject: [PATCH 2/6] update depreciated paths --- InvenTree/InvenTree/urls.py | 162 +++++++++--------- InvenTree/barcodes/api.py | 8 +- InvenTree/build/api.py | 34 ++-- InvenTree/build/urls.py | 12 +- InvenTree/common/api.py | 28 +-- InvenTree/company/api.py | 30 ++-- InvenTree/company/urls.py | 20 +-- InvenTree/order/api.py | 78 ++++----- InvenTree/order/urls.py | 36 ++-- InvenTree/part/api.py | 90 +++++----- InvenTree/part/urls.py | 58 +++---- InvenTree/plugin/api.py | 16 +- .../plugin/builtin/integration/mixins.py | 4 +- .../plugin/samples/integration/sample.py | 3 +- InvenTree/plugin/urls.py | 4 +- InvenTree/report/api.py | 53 +++--- InvenTree/stock/api.py | 50 +++--- InvenTree/stock/urls.py | 40 ++--- InvenTree/users/api.py | 16 +- 19 files changed, 370 insertions(+), 372 deletions(-) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index ec8b891f93..e50a64a988 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -4,7 +4,7 @@ Top-level URL lookup for InvenTree application. Passes URL lookup downstream to each app as required. """ -from django.conf.urls import url, include +from django.urls import include, path, re_path from django.urls import path from django.contrib import admin @@ -56,144 +56,144 @@ apipatterns = [] if settings.PLUGINS_ENABLED: apipatterns.append( - url(r'^plugin/', include(plugin_api_urls)) + re_path(r'^plugin/', include(plugin_api_urls)) ) apipatterns += [ - url(r'^barcode/', include(barcode_api_urls)), - url(r'^settings/', include(settings_api_urls)), - url(r'^part/', include(part_api_urls)), - url(r'^bom/', include(bom_api_urls)), - url(r'^company/', include(company_api_urls)), - url(r'^stock/', include(stock_api_urls)), - url(r'^build/', include(build_api_urls)), - url(r'^order/', include(order_api_urls)), - url(r'^label/', include(label_api_urls)), - url(r'^report/', include(report_api_urls)), + re_path(r'^barcode/', include(barcode_api_urls)), + re_path(r'^settings/', include(settings_api_urls)), + re_path(r'^part/', include(part_api_urls)), + re_path(r'^bom/', include(bom_api_urls)), + re_path(r'^company/', include(company_api_urls)), + re_path(r'^stock/', include(stock_api_urls)), + re_path(r'^build/', include(build_api_urls)), + re_path(r'^order/', include(order_api_urls)), + re_path(r'^label/', include(label_api_urls)), + re_path(r'^report/', include(report_api_urls)), # User URLs - url(r'^user/', include(user_urls)), + re_path(r'^user/', include(user_urls)), # Plugin endpoints - url(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'), + re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'), # Webhook enpoint path('', include(common_api_urls)), # InvenTree information endpoint - url(r'^$', InfoView.as_view(), name='api-inventree-info'), + path('', InfoView.as_view(), name='api-inventree-info'), # Unknown endpoint - url(r'^.*$', NotFoundView.as_view(), name='api-404'), + re_path(r'^.*$', NotFoundView.as_view(), name='api-404'), ] settings_urls = [ - url(r'^i18n/?', include('django.conf.urls.i18n')), + re_path(r'^i18n/?', include('django.conf.urls.i18n')), - url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'), - url(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'), + re_path(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'), + re_path(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'), - url(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'), + re_path(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'), # Catch any other urls - url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'), + re_path(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'), ] notifications_urls = [ # Catch any other urls - url(r'^.*$', NotificationsView.as_view(), name='notifications'), + re_path(r'^.*$', NotificationsView.as_view(), name='notifications'), ] # These javascript files are served "dynamically" - i.e. rendered on demand dynamic_javascript_urls = [ - url(r'^calendar.js', DynamicJsView.as_view(template_name='js/dynamic/calendar.js'), name='calendar.js'), - url(r'^nav.js', DynamicJsView.as_view(template_name='js/dynamic/nav.js'), name='nav.js'), - url(r'^settings.js', DynamicJsView.as_view(template_name='js/dynamic/settings.js'), name='settings.js'), + re_path(r'^calendar.js', DynamicJsView.as_view(template_name='js/dynamic/calendar.js'), name='calendar.js'), + re_path(r'^nav.js', DynamicJsView.as_view(template_name='js/dynamic/nav.js'), name='nav.js'), + re_path(r'^settings.js', DynamicJsView.as_view(template_name='js/dynamic/settings.js'), name='settings.js'), ] # These javascript files are pased through the Django translation layer translated_javascript_urls = [ - url(r'^api.js', DynamicJsView.as_view(template_name='js/translated/api.js'), name='api.js'), - url(r'^attachment.js', DynamicJsView.as_view(template_name='js/translated/attachment.js'), name='attachment.js'), - url(r'^barcode.js', DynamicJsView.as_view(template_name='js/translated/barcode.js'), name='barcode.js'), - url(r'^bom.js', DynamicJsView.as_view(template_name='js/translated/bom.js'), name='bom.js'), - url(r'^build.js', DynamicJsView.as_view(template_name='js/translated/build.js'), name='build.js'), - url(r'^company.js', DynamicJsView.as_view(template_name='js/translated/company.js'), name='company.js'), - url(r'^filters.js', DynamicJsView.as_view(template_name='js/translated/filters.js'), name='filters.js'), - url(r'^forms.js', DynamicJsView.as_view(template_name='js/translated/forms.js'), name='forms.js'), - url(r'^helpers.js', DynamicJsView.as_view(template_name='js/translated/helpers.js'), name='helpers.js'), - url(r'^label.js', DynamicJsView.as_view(template_name='js/translated/label.js'), name='label.js'), - url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/translated/model_renderers.js'), name='model_renderers.js'), - url(r'^modals.js', DynamicJsView.as_view(template_name='js/translated/modals.js'), name='modals.js'), - url(r'^order.js', DynamicJsView.as_view(template_name='js/translated/order.js'), name='order.js'), - url(r'^part.js', DynamicJsView.as_view(template_name='js/translated/part.js'), name='part.js'), - url(r'^report.js', DynamicJsView.as_view(template_name='js/translated/report.js'), name='report.js'), - url(r'^search.js', DynamicJsView.as_view(template_name='js/translated/search.js'), name='search.js'), - url(r'^stock.js', DynamicJsView.as_view(template_name='js/translated/stock.js'), name='stock.js'), - url(r'^plugin.js', DynamicJsView.as_view(template_name='js/translated/plugin.js'), name='plugin.js'), - url(r'^tables.js', DynamicJsView.as_view(template_name='js/translated/tables.js'), name='tables.js'), - url(r'^table_filters.js', DynamicJsView.as_view(template_name='js/translated/table_filters.js'), name='table_filters.js'), - url(r'^notification.js', DynamicJsView.as_view(template_name='js/translated/notification.js'), name='notification.js'), + re_path(r'^api.js', DynamicJsView.as_view(template_name='js/translated/api.js'), name='api.js'), + re_path(r'^attachment.js', DynamicJsView.as_view(template_name='js/translated/attachment.js'), name='attachment.js'), + re_path(r'^barcode.js', DynamicJsView.as_view(template_name='js/translated/barcode.js'), name='barcode.js'), + re_path(r'^bom.js', DynamicJsView.as_view(template_name='js/translated/bom.js'), name='bom.js'), + re_path(r'^build.js', DynamicJsView.as_view(template_name='js/translated/build.js'), name='build.js'), + re_path(r'^company.js', DynamicJsView.as_view(template_name='js/translated/company.js'), name='company.js'), + re_path(r'^filters.js', DynamicJsView.as_view(template_name='js/translated/filters.js'), name='filters.js'), + re_path(r'^forms.js', DynamicJsView.as_view(template_name='js/translated/forms.js'), name='forms.js'), + re_path(r'^helpers.js', DynamicJsView.as_view(template_name='js/translated/helpers.js'), name='helpers.js'), + re_path(r'^label.js', DynamicJsView.as_view(template_name='js/translated/label.js'), name='label.js'), + re_path(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/translated/model_renderers.js'), name='model_renderers.js'), + re_path(r'^modals.js', DynamicJsView.as_view(template_name='js/translated/modals.js'), name='modals.js'), + re_path(r'^order.js', DynamicJsView.as_view(template_name='js/translated/order.js'), name='order.js'), + re_path(r'^part.js', DynamicJsView.as_view(template_name='js/translated/part.js'), name='part.js'), + re_path(r'^report.js', DynamicJsView.as_view(template_name='js/translated/report.js'), name='report.js'), + re_path(r'^search.js', DynamicJsView.as_view(template_name='js/translated/search.js'), name='search.js'), + re_path(r'^stock.js', DynamicJsView.as_view(template_name='js/translated/stock.js'), name='stock.js'), + re_path(r'^plugin.js', DynamicJsView.as_view(template_name='js/translated/plugin.js'), name='plugin.js'), + re_path(r'^tables.js', DynamicJsView.as_view(template_name='js/translated/tables.js'), name='tables.js'), + re_path(r'^table_filters.js', DynamicJsView.as_view(template_name='js/translated/table_filters.js'), name='table_filters.js'), + re_path(r'^notification.js', DynamicJsView.as_view(template_name='js/translated/notification.js'), name='notification.js'), ] backendpatterns = [ # "Dynamic" javascript files which are rendered using InvenTree templating. - url(r'^js/dynamic/', include(dynamic_javascript_urls)), - url(r'^js/i18n/', include(translated_javascript_urls)), + re_path(r'^js/dynamic/', include(dynamic_javascript_urls)), + re_path(r'^js/i18n/', include(translated_javascript_urls)), - url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), - url(r'^auth/?', auth_request), + re_path(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), + re_path(r'^auth/?', auth_request), - url(r'^api/', include(apipatterns)), - url(r'^api-doc/', include_docs_urls(title='InvenTree API')), + re_path(r'^api/', include(apipatterns)), + re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')), # 3rd party endpoints - url(r'^markdownx/', include('markdownx.urls')), + re_path(r'^markdownx/', include('markdownx.urls')), ] frontendpatterns = [ - url(r'^part/', include(part_urls)), - url(r'^manufacturer-part/', include(manufacturer_part_urls)), - url(r'^supplier-part/', include(supplier_part_urls)), + re_path(r'^part/', include(part_urls)), + re_path(r'^manufacturer-part/', include(manufacturer_part_urls)), + re_path(r'^supplier-part/', include(supplier_part_urls)), - url(r'^common/', include(common_urls)), + re_path(r'^common/', include(common_urls)), - url(r'^stock/', include(stock_urls)), + re_path(r'^stock/', include(stock_urls)), - url(r'^company/', include(company_urls)), - url(r'^order/', include(order_urls)), + re_path(r'^company/', include(company_urls)), + re_path(r'^order/', include(order_urls)), - url(r'^build/', include(build_urls)), + re_path(r'^build/', include(build_urls)), - url(r'^settings/', include(settings_urls)), + re_path(r'^settings/', include(settings_urls)), - url(r'^notifications/', include(notifications_urls)), + re_path(r'^notifications/', include(notifications_urls)), - url(r'^edit-user/', EditUserView.as_view(), name='edit-user'), - url(r'^set-password/', SetPasswordView.as_view(), name='set-password'), + re_path(r'^edit-user/', EditUserView.as_view(), name='edit-user'), + re_path(r'^set-password/', SetPasswordView.as_view(), name='set-password'), - url(r'^index/', IndexView.as_view(), name='index'), - url(r'^search/', SearchView.as_view(), name='search'), - url(r'^stats/', DatabaseStatsView.as_view(), name='stats'), + re_path(r'^index/', IndexView.as_view(), name='index'), + re_path(r'^search/', SearchView.as_view(), name='search'), + re_path(r'^stats/', DatabaseStatsView.as_view(), name='stats'), # admin sites - url(f'^{settings.INVENTREE_ADMIN_URL}/error_log/', include('error_report.urls')), - url(f'^{settings.INVENTREE_ADMIN_URL}/shell/', include('django_admin_shell.urls')), - url(f'^{settings.INVENTREE_ADMIN_URL}/', admin.site.urls, name='inventree-admin'), + re_path(f'^{settings.INVENTREE_ADMIN_URL}/error_log/', include('error_report.urls')), + re_path(f'^{settings.INVENTREE_ADMIN_URL}/shell/', include('django_admin_shell.urls')), + re_path(f'^{settings.INVENTREE_ADMIN_URL}/', admin.site.urls, name='inventree-admin'), # DB user sessions - url(r'^accounts/sessions/other/delete/$', view=CustomSessionDeleteOtherView.as_view(), name='session_delete_other', ), - url(r'^accounts/sessions/(?P\w+)/delete/$', view=CustomSessionDeleteView.as_view(), name='session_delete', ), + path('accounts/sessions/other/delete/', view=CustomSessionDeleteOtherView.as_view(), name='session_delete_other', ), + re_path(r'^accounts/sessions/(?P\w+)/delete/$', view=CustomSessionDeleteView.as_view(), name='session_delete', ), # Single Sign On / allauth # overrides of urlpatterns - url(r'^accounts/email/', CustomEmailView.as_view(), name='account_email'), - url(r'^accounts/social/connections/', CustomConnectionsView.as_view(), name='socialaccount_connections'), - url(r"^accounts/password/reset/key/(?P[0-9A-Za-z]+)-(?P.+)/$", CustomPasswordResetFromKeyView.as_view(), name="account_reset_password_from_key"), - url(r'^accounts/', include('allauth_2fa.urls')), # MFA support - url(r'^accounts/', include('allauth.urls')), # included urlpatterns + re_path(r'^accounts/email/', CustomEmailView.as_view(), name='account_email'), + re_path(r'^accounts/social/connections/', CustomConnectionsView.as_view(), name='socialaccount_connections'), + re_path(r"^accounts/password/reset/key/(?P[0-9A-Za-z]+)-(?P.+)/$", CustomPasswordResetFromKeyView.as_view(), name="account_reset_password_from_key"), + re_path(r'^accounts/', include('allauth_2fa.urls')), # MFA support + re_path(r'^accounts/', include('allauth.urls')), # included urlpatterns ] # Append custom plugin URLs (if plugin support is enabled) @@ -201,8 +201,8 @@ if settings.PLUGINS_ENABLED: frontendpatterns.append(get_plugin_urls()) urlpatterns = [ - url('', include(frontendpatterns)), - url('', include(backendpatterns)), + re_path('', include(frontendpatterns)), + re_path('', include(backendpatterns)), ] # Server running in "DEBUG" mode? @@ -221,4 +221,4 @@ if settings.DEBUG: ] + urlpatterns # Send any unknown URLs to the parts page -urlpatterns += [url(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')] +urlpatterns += [re_path(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')] diff --git a/InvenTree/barcodes/api.py b/InvenTree/barcodes/api.py index 047db357a4..f36e4b1703 100644 --- a/InvenTree/barcodes/api.py +++ b/InvenTree/barcodes/api.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from django.urls import reverse -from django.conf.urls import url -from django.utils.translation import ugettext_lazy as _ +from django.urls import path, re_path +from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import ValidationError from rest_framework import permissions @@ -240,8 +240,8 @@ class BarcodeAssign(APIView): barcode_api_urls = [ - url(r'^link/$', BarcodeAssign.as_view(), name='api-barcode-link'), + path('link/', BarcodeAssign.as_view(), name='api-barcode-link'), # Catch-all performs barcode 'scan' - url(r'^.*$', BarcodeScan.as_view(), name='api-barcode-scan'), + re_path(r'^.*$', BarcodeScan.as_view(), name='api-barcode-scan'), ] diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index a720f7cbe0..913a500d41 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -5,7 +5,7 @@ JSON API for the Build app # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.conf.urls import url, include +from django.urls import include, re_path from rest_framework import filters, generics @@ -508,29 +508,29 @@ class BuildAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMix build_api_urls = [ # Attachments - url(r'^attachment/', include([ - url(r'^(?P\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'), - url(r'^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'), + re_path(r'^attachment/', include([ + re_path(r'^(?P\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'), + re_path(r'^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'), ])), # Build Items - url(r'^item/', include([ - url(r'^(?P\d+)/', BuildItemDetail.as_view(), name='api-build-item-detail'), - url(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'), + re_path(r'^item/', include([ + re_path(r'^(?P\d+)/', BuildItemDetail.as_view(), name='api-build-item-detail'), + re_path(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'), ])), # Build Detail - url(r'^(?P\d+)/', include([ - url(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'), - url(r'^auto-allocate/', BuildAutoAllocate.as_view(), name='api-build-auto-allocate'), - url(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'), - url(r'^create-output/', BuildOutputCreate.as_view(), name='api-build-output-create'), - url(r'^delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'), - url(r'^finish/', BuildFinish.as_view(), name='api-build-finish'), - url(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'), - url(r'^.*$', BuildDetail.as_view(), name='api-build-detail'), + re_path(r'^(?P\d+)/', 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'^finish/', BuildFinish.as_view(), name='api-build-finish'), + re_path(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'), + re_path(r'^.*$', BuildDetail.as_view(), name='api-build-detail'), ])), # Build List - url(r'^.*$', BuildList.as_view(), name='api-build-list'), + re_path(r'^.*$', BuildList.as_view(), name='api-build-list'), ] diff --git a/InvenTree/build/urls.py b/InvenTree/build/urls.py index 0058e8a527..520d97ef6a 100644 --- a/InvenTree/build/urls.py +++ b/InvenTree/build/urls.py @@ -2,20 +2,20 @@ URL lookup for Build app """ -from django.conf.urls import url, include +from django.urls import include, re_path from . import views build_detail_urls = [ - url(r'^cancel/', views.BuildCancel.as_view(), name='build-cancel'), - url(r'^delete/', views.BuildDelete.as_view(), name='build-delete'), + re_path(r'^cancel/', views.BuildCancel.as_view(), name='build-cancel'), + re_path(r'^delete/', views.BuildDelete.as_view(), name='build-delete'), - url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'), + re_path(r'^.*$', views.BuildDetail.as_view(), name='build-detail'), ] build_urls = [ - url(r'^(?P\d+)/', include(build_detail_urls)), + re_path(r'^(?P\d+)/', include(build_detail_urls)), - url(r'.*$', views.BuildIndex.as_view(), name='build-index'), + re_path(r'.*$', views.BuildIndex.as_view(), name='build-index'), ] diff --git a/InvenTree/common/api.py b/InvenTree/common/api.py index d725799894..2f7f3e2ca8 100644 --- a/InvenTree/common/api.py +++ b/InvenTree/common/api.py @@ -11,7 +11,7 @@ from django.http.response import HttpResponse from django.utils.decorators import method_decorator from django.urls import path from django.views.decorators.csrf import csrf_exempt -from django.conf.urls import url, include +from django.urls import include, re_path from rest_framework.views import APIView from rest_framework.response import Response @@ -336,21 +336,21 @@ class NotificationReadAll(generics.RetrieveAPIView): settings_api_urls = [ # User settings - url(r'^user/', include([ + re_path(r'^user/', include([ # User Settings Detail - url(r'^(?P\d+)/', UserSettingsDetail.as_view(), name='api-user-setting-detail'), + re_path(r'^(?P\d+)/', UserSettingsDetail.as_view(), name='api-user-setting-detail'), # User Settings List - url(r'^.*$', UserSettingsList.as_view(), name='api-user-setting-list'), + re_path(r'^.*$', UserSettingsList.as_view(), name='api-user-setting-list'), ])), # Global settings - url(r'^global/', include([ + re_path(r'^global/', include([ # Global Settings Detail - url(r'^(?P\d+)/', GlobalSettingsDetail.as_view(), name='api-global-setting-detail'), + re_path(r'^(?P\d+)/', GlobalSettingsDetail.as_view(), name='api-global-setting-detail'), # Global Settings List - url(r'^.*$', GlobalSettingsList.as_view(), name='api-global-setting-list'), + re_path(r'^.*$', GlobalSettingsList.as_view(), name='api-global-setting-list'), ])), ] @@ -359,18 +359,18 @@ common_api_urls = [ path('webhook//', WebhookView.as_view(), name='api-webhook'), # Notifications - url(r'^notifications/', include([ + re_path(r'^notifications/', include([ # Individual purchase order detail URLs - url(r'^(?P\d+)/', include([ - url(r'^read/', NotificationRead.as_view(), name='api-notifications-read'), - url(r'^unread/', NotificationUnread.as_view(), name='api-notifications-unread'), - url(r'.*$', NotificationDetail.as_view(), name='api-notifications-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^read/', NotificationRead.as_view(), name='api-notifications-read'), + re_path(r'^unread/', NotificationUnread.as_view(), name='api-notifications-unread'), + re_path(r'.*$', NotificationDetail.as_view(), name='api-notifications-detail'), ])), # Read all - url(r'^readall/', NotificationReadAll.as_view(), name='api-notifications-readall'), + re_path(r'^readall/', NotificationReadAll.as_view(), name='api-notifications-readall'), # Notification messages list - url(r'^.*$', NotificationList.as_view(), name='api-notifications-list'), + re_path(r'^.*$', NotificationList.as_view(), name='api-notifications-list'), ])), ] diff --git a/InvenTree/company/api.py b/InvenTree/company/api.py index 83d24e0858..e4a589d9e5 100644 --- a/InvenTree/company/api.py +++ b/InvenTree/company/api.py @@ -11,7 +11,7 @@ from django_filters import rest_framework as rest_filters from rest_framework import filters from rest_framework import generics -from django.conf.urls import url, include +from django.urls import include, re_path from django.db.models import Q from InvenTree.helpers import str2bool @@ -390,42 +390,42 @@ class SupplierPriceBreakDetail(generics.RetrieveUpdateDestroyAPIView): manufacturer_part_api_urls = [ - url(r'^parameter/', include([ - url(r'^(?P\d+)/', ManufacturerPartParameterDetail.as_view(), name='api-manufacturer-part-parameter-detail'), + re_path(r'^parameter/', include([ + re_path(r'^(?P\d+)/', ManufacturerPartParameterDetail.as_view(), name='api-manufacturer-part-parameter-detail'), # Catch anything else - url(r'^.*$', ManufacturerPartParameterList.as_view(), name='api-manufacturer-part-parameter-list'), + re_path(r'^.*$', ManufacturerPartParameterList.as_view(), name='api-manufacturer-part-parameter-list'), ])), - url(r'^(?P\d+)/?', ManufacturerPartDetail.as_view(), name='api-manufacturer-part-detail'), + re_path(r'^(?P\d+)/?', ManufacturerPartDetail.as_view(), name='api-manufacturer-part-detail'), # Catch anything else - url(r'^.*$', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'), + re_path(r'^.*$', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'), ] supplier_part_api_urls = [ - url(r'^(?P\d+)/?', SupplierPartDetail.as_view(), name='api-supplier-part-detail'), + re_path(r'^(?P\d+)/?', SupplierPartDetail.as_view(), name='api-supplier-part-detail'), # Catch anything else - url(r'^.*$', SupplierPartList.as_view(), name='api-supplier-part-list'), + re_path(r'^.*$', SupplierPartList.as_view(), name='api-supplier-part-list'), ] company_api_urls = [ - url(r'^part/manufacturer/', include(manufacturer_part_api_urls)), + re_path(r'^part/manufacturer/', include(manufacturer_part_api_urls)), - url(r'^part/', include(supplier_part_api_urls)), + re_path(r'^part/', include(supplier_part_api_urls)), # Supplier price breaks - url(r'^price-break/', include([ + re_path(r'^price-break/', include([ - url(r'^(?P\d+)/?', SupplierPriceBreakDetail.as_view(), name='api-part-supplier-price-detail'), - url(r'^.*$', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'), + re_path(r'^(?P\d+)/?', SupplierPriceBreakDetail.as_view(), name='api-part-supplier-price-detail'), + re_path(r'^.*$', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'), ])), - url(r'^(?P\d+)/?', CompanyDetail.as_view(), name='api-company-detail'), + re_path(r'^(?P\d+)/?', CompanyDetail.as_view(), name='api-company-detail'), - url(r'^.*$', CompanyList.as_view(), name='api-company-list'), + re_path(r'^.*$', CompanyList.as_view(), name='api-company-list'), ] diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py index 377a37706d..25ebdbb771 100644 --- a/InvenTree/company/urls.py +++ b/InvenTree/company/urls.py @@ -2,37 +2,37 @@ URL lookup for Company app """ -from django.conf.urls import url, include +from django.urls import include, re_path from . import views company_detail_urls = [ - url(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'), + re_path(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'), # Any other URL - url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'), + re_path(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'), ] company_urls = [ - url(r'^(?P\d+)/', include(company_detail_urls)), + re_path(r'^(?P\d+)/', include(company_detail_urls)), - url(r'suppliers/', views.CompanyIndex.as_view(), name='supplier-index'), - url(r'manufacturers/', views.CompanyIndex.as_view(), name='manufacturer-index'), - url(r'customers/', views.CompanyIndex.as_view(), name='customer-index'), + 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'), # Redirect any other patterns to the 'company' index which displays all companies - url(r'^.*$', views.CompanyIndex.as_view(), name='company-index'), + re_path(r'^.*$', views.CompanyIndex.as_view(), name='company-index'), ] manufacturer_part_urls = [ - url(r'^(?P\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'), + re_path(r'^(?P\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'), ] supplier_part_urls = [ - url(r'^(?P\d+)/', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'), + re_path(r'^(?P\d+)/', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'), ] diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 0b0fe3185a..a54c370121 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -5,7 +5,7 @@ JSON API for the Order app # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.conf.urls import url, include +from django.urls import include, path, re_path from django.db.models import Q, F from django_filters import rest_framework as rest_filters @@ -1096,78 +1096,78 @@ class PurchaseOrderAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, Attac order_api_urls = [ # API endpoints for purchase orders - url(r'^po/', include([ + re_path(r'^po/', include([ # Purchase order attachments - url(r'attachment/', include([ - url(r'^(?P\d+)/$', PurchaseOrderAttachmentDetail.as_view(), name='api-po-attachment-detail'), - url(r'^.*$', PurchaseOrderAttachmentList.as_view(), name='api-po-attachment-list'), + re_path(r'attachment/', include([ + path('/', PurchaseOrderAttachmentDetail.as_view(), name='api-po-attachment-detail'), + re_path(r'^.*$', PurchaseOrderAttachmentList.as_view(), name='api-po-attachment-list'), ])), # Individual purchase order detail URLs - url(r'^(?P\d+)/', include([ - url(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'), - url(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'), + re_path(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'), ])), # Purchase order list - url(r'^.*$', PurchaseOrderList.as_view(), name='api-po-list'), + re_path(r'^.*$', PurchaseOrderList.as_view(), name='api-po-list'), ])), # API endpoints for purchase order line items - url(r'^po-line/', include([ - url(r'^(?P\d+)/$', PurchaseOrderLineItemDetail.as_view(), name='api-po-line-detail'), - url(r'^.*$', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'), + re_path(r'^po-line/', include([ + path('/', PurchaseOrderLineItemDetail.as_view(), name='api-po-line-detail'), + re_path(r'^.*$', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'), ])), # API endpoints for purchase order extra line - url(r'^po-extra-line/', include([ - url(r'^(?P\d+)/$', PurchaseOrderExtraLineDetail.as_view(), name='api-po-extra-line-detail'), - url(r'^$', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list'), + re_path(r'^po-extra-line/', include([ + path('/', PurchaseOrderExtraLineDetail.as_view(), name='api-po-extra-line-detail'), + path('', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list'), ])), # API endpoints for sales ordesr - url(r'^so/', include([ - url(r'attachment/', include([ - url(r'^(?P\d+)/$', SalesOrderAttachmentDetail.as_view(), name='api-so-attachment-detail'), - url(r'^.*$', SalesOrderAttachmentList.as_view(), name='api-so-attachment-list'), + re_path(r'^so/', include([ + re_path(r'attachment/', include([ + path('/', SalesOrderAttachmentDetail.as_view(), name='api-so-attachment-detail'), + re_path(r'^.*$', SalesOrderAttachmentList.as_view(), name='api-so-attachment-list'), ])), - url(r'^shipment/', include([ - url(r'^(?P\d+)/', include([ - url(r'^ship/$', SalesOrderShipmentComplete.as_view(), name='api-so-shipment-ship'), - url(r'^.*$', SalesOrderShipmentDetail.as_view(), name='api-so-shipment-detail'), + re_path(r'^shipment/', include([ + re_path(r'^(?P\d+)/', include([ + path('ship/', SalesOrderShipmentComplete.as_view(), name='api-so-shipment-ship'), + re_path(r'^.*$', SalesOrderShipmentDetail.as_view(), name='api-so-shipment-detail'), ])), - url(r'^.*$', SalesOrderShipmentList.as_view(), name='api-so-shipment-list'), + re_path(r'^.*$', SalesOrderShipmentList.as_view(), name='api-so-shipment-list'), ])), # Sales order detail view - url(r'^(?P\d+)/', include([ - url(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'), - url(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'), - url(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'), - url(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'), + re_path(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'), + re_path(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'), + re_path(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'), ])), # Sales order list view - url(r'^.*$', SalesOrderList.as_view(), name='api-so-list'), + re_path(r'^.*$', SalesOrderList.as_view(), name='api-so-list'), ])), # API endpoints for sales order line items - url(r'^so-line/', include([ - url(r'^(?P\d+)/$', SalesOrderLineItemDetail.as_view(), name='api-so-line-detail'), - url(r'^$', SalesOrderLineItemList.as_view(), name='api-so-line-list'), + re_path(r'^so-line/', include([ + path('/', SalesOrderLineItemDetail.as_view(), name='api-so-line-detail'), + path('', SalesOrderLineItemList.as_view(), name='api-so-line-list'), ])), # API endpoints for sales order extra line - url(r'^so-extra-line/', include([ - url(r'^(?P\d+)/$', SalesOrderExtraLineDetail.as_view(), name='api-so-extra-line-detail'), - url(r'^$', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'), + re_path(r'^so-extra-line/', include([ + path('/', SalesOrderExtraLineDetail.as_view(), name='api-so-extra-line-detail'), + path('', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'), ])), # API endpoints for sales order allocations - url(r'^so-allocation/', include([ - url(r'^(?P\d+)/$', SalesOrderAllocationDetail.as_view(), name='api-so-allocation-detail'), - url(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'), + re_path(r'^so-allocation/', include([ + path('/', SalesOrderAllocationDetail.as_view(), name='api-so-allocation-detail'), + re_path(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'), ])), ] diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 504145892a..54be93905f 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -5,50 +5,50 @@ URL lookup for the Order app. Provides URL endpoints for: - Detail view of Purchase Orders """ -from django.conf.urls import url, include +from django.urls import include, re_path from . import views purchase_order_detail_urls = [ - url(r'^cancel/', views.PurchaseOrderCancel.as_view(), name='po-cancel'), - url(r'^issue/', views.PurchaseOrderIssue.as_view(), name='po-issue'), - url(r'^complete/', views.PurchaseOrderComplete.as_view(), name='po-complete'), + re_path(r'^cancel/', views.PurchaseOrderCancel.as_view(), name='po-cancel'), + re_path(r'^issue/', views.PurchaseOrderIssue.as_view(), name='po-issue'), + re_path(r'^complete/', views.PurchaseOrderComplete.as_view(), name='po-complete'), - url(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'), - url(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'), + re_path(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'), + re_path(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'), - url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'), + re_path(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'), ] purchase_order_urls = [ - url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'), - url(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'), + re_path(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'), + re_path(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'), # Display detail view for a single purchase order - url(r'^(?P\d+)/', include(purchase_order_detail_urls)), + re_path(r'^(?P\d+)/', include(purchase_order_detail_urls)), # Display complete list of purchase orders - url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'), + re_path(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'), ] sales_order_detail_urls = [ - url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'), - url(r'^export/', views.SalesOrderExport.as_view(), name='so-export'), + re_path(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'), + re_path(r'^export/', views.SalesOrderExport.as_view(), name='so-export'), - url(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'), + re_path(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'), ] sales_order_urls = [ # Display detail view for a single SalesOrder - url(r'^(?P\d+)/', include(sales_order_detail_urls)), + re_path(r'^(?P\d+)/', include(sales_order_detail_urls)), # Display list of all sales orders - url(r'^.*$', views.SalesOrderIndex.as_view(), name='so-index'), + re_path(r'^.*$', views.SalesOrderIndex.as_view(), name='so-index'), ] order_urls = [ - url(r'^purchase-order/', include(purchase_order_urls)), - url(r'^sales-order/', include(sales_order_urls)), + re_path(r'^purchase-order/', include(purchase_order_urls)), + re_path(r'^sales-order/', include(sales_order_urls)), ] diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 3752f7daf4..b2acaf678e 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import datetime -from django.conf.urls import url, include +from django.urls import include, path, re_path from django.http import JsonResponse from django.db.models import Q, F, Count, Min, Max, Avg from django.db import transaction @@ -1916,100 +1916,100 @@ class BomItemSubstituteDetail(generics.RetrieveUpdateDestroyAPIView): part_api_urls = [ # Base URL for PartCategory API endpoints - url(r'^category/', include([ - url(r'^tree/', CategoryTree.as_view(), name='api-part-category-tree'), - url(r'^parameters/', CategoryParameterList.as_view(), name='api-part-category-parameter-list'), + re_path(r'^category/', include([ + re_path(r'^tree/', CategoryTree.as_view(), name='api-part-category-tree'), + re_path(r'^parameters/', CategoryParameterList.as_view(), name='api-part-category-parameter-list'), - url(r'^(?P\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'), - url(r'^$', CategoryList.as_view(), name='api-part-category-list'), + re_path(r'^(?P\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'), + path('', CategoryList.as_view(), name='api-part-category-list'), ])), # Base URL for PartTestTemplate API endpoints - url(r'^test-template/', include([ - url(r'^(?P\d+)/', PartTestTemplateDetail.as_view(), name='api-part-test-template-detail'), - url(r'^$', PartTestTemplateList.as_view(), name='api-part-test-template-list'), + re_path(r'^test-template/', include([ + re_path(r'^(?P\d+)/', PartTestTemplateDetail.as_view(), name='api-part-test-template-detail'), + path('', PartTestTemplateList.as_view(), name='api-part-test-template-list'), ])), # Base URL for PartAttachment API endpoints - url(r'^attachment/', include([ - url(r'^(?P\d+)/', PartAttachmentDetail.as_view(), name='api-part-attachment-detail'), - url(r'^$', PartAttachmentList.as_view(), name='api-part-attachment-list'), + re_path(r'^attachment/', include([ + re_path(r'^(?P\d+)/', PartAttachmentDetail.as_view(), name='api-part-attachment-detail'), + path('', PartAttachmentList.as_view(), name='api-part-attachment-list'), ])), # Base URL for part sale pricing - url(r'^sale-price/', include([ - url(r'^(?P\d+)/', PartSalePriceDetail.as_view(), name='api-part-sale-price-detail'), - url(r'^.*$', PartSalePriceList.as_view(), name='api-part-sale-price-list'), + re_path(r'^sale-price/', include([ + re_path(r'^(?P\d+)/', PartSalePriceDetail.as_view(), name='api-part-sale-price-detail'), + re_path(r'^.*$', PartSalePriceList.as_view(), name='api-part-sale-price-list'), ])), # Base URL for part internal pricing - url(r'^internal-price/', include([ - url(r'^(?P\d+)/', PartInternalPriceDetail.as_view(), name='api-part-internal-price-detail'), - url(r'^.*$', PartInternalPriceList.as_view(), name='api-part-internal-price-list'), + re_path(r'^internal-price/', include([ + re_path(r'^(?P\d+)/', PartInternalPriceDetail.as_view(), name='api-part-internal-price-detail'), + re_path(r'^.*$', PartInternalPriceList.as_view(), name='api-part-internal-price-list'), ])), # Base URL for PartRelated API endpoints - url(r'^related/', include([ - url(r'^(?P\d+)/', PartRelatedDetail.as_view(), name='api-part-related-detail'), - url(r'^.*$', PartRelatedList.as_view(), name='api-part-related-list'), + re_path(r'^related/', include([ + re_path(r'^(?P\d+)/', PartRelatedDetail.as_view(), name='api-part-related-detail'), + re_path(r'^.*$', PartRelatedList.as_view(), name='api-part-related-list'), ])), # Base URL for PartParameter API endpoints - url(r'^parameter/', include([ - url(r'^template/$', PartParameterTemplateList.as_view(), name='api-part-parameter-template-list'), + re_path(r'^parameter/', include([ + path('template/', PartParameterTemplateList.as_view(), name='api-part-parameter-template-list'), - url(r'^(?P\d+)/', PartParameterDetail.as_view(), name='api-part-parameter-detail'), - url(r'^.*$', PartParameterList.as_view(), name='api-part-parameter-list'), + re_path(r'^(?P\d+)/', PartParameterDetail.as_view(), name='api-part-parameter-detail'), + re_path(r'^.*$', PartParameterList.as_view(), name='api-part-parameter-list'), ])), - url(r'^thumbs/', include([ - url(r'^$', PartThumbs.as_view(), name='api-part-thumbs'), - url(r'^(?P\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'), + re_path(r'^thumbs/', include([ + path('', PartThumbs.as_view(), name='api-part-thumbs'), + re_path(r'^(?P\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'), ])), - url(r'^(?P\d+)/', include([ + re_path(r'^(?P\d+)/', include([ # Endpoint for extra serial number information - url(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'), + re_path(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'), # Endpoint for future scheduling information - url(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'), + re_path(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'), # Endpoint for duplicating a BOM for the specific Part - url(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'), + re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'), # Endpoint for validating a BOM for the specific Part - url(r'^bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'), + re_path(r'^bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'), # Part detail endpoint - url(r'^.*$', PartDetail.as_view(), name='api-part-detail'), + re_path(r'^.*$', PartDetail.as_view(), name='api-part-detail'), ])), - url(r'^.*$', PartList.as_view(), name='api-part-list'), + re_path(r'^.*$', PartList.as_view(), name='api-part-list'), ] bom_api_urls = [ - url(r'^substitute/', include([ + re_path(r'^substitute/', include([ # Detail view - url(r'^(?P\d+)/', BomItemSubstituteDetail.as_view(), name='api-bom-substitute-detail'), + re_path(r'^(?P\d+)/', BomItemSubstituteDetail.as_view(), name='api-bom-substitute-detail'), # Catch all - url(r'^.*$', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'), + re_path(r'^.*$', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'), ])), # BOM Item Detail - url(r'^(?P\d+)/', include([ - url(r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'), - url(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'), + re_path(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'), ])), # API endpoint URLs for importing BOM data - url(r'^import/upload/', BomImportUpload.as_view(), name='api-bom-import-upload'), - url(r'^import/extract/', BomImportExtract.as_view(), name='api-bom-import-extract'), - url(r'^import/submit/', BomImportSubmit.as_view(), name='api-bom-import-submit'), + 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'), # Catch-all - url(r'^.*$', BomList.as_view(), name='api-bom-list'), + re_path(r'^.*$', BomList.as_view(), name='api-bom-list'), ] diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 04d2b0a5f8..a9da7329a6 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -8,53 +8,53 @@ URL lookup for Part app. Provides URL endpoints for: """ -from django.conf.urls import url, include +from django.urls import include, re_path from . import views part_parameter_urls = [ - url(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), - url(r'^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), - url(r'^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), + re_path(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), + re_path(r'^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), + re_path(r'^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), ] part_detail_urls = [ - url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'), - url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'), + re_path(r'^delete/?', views.PartDelete.as_view(), name='part-delete'), + re_path(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'), - url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'), + re_path(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'), - url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'), + re_path(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'), - url(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'), + re_path(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'), # Normal thumbnail with form - url(r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'), - url(r'^thumb-download/', views.PartImageDownloadFromURL.as_view(), name='part-image-download'), + re_path(r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'), + re_path(r'^thumb-download/', views.PartImageDownloadFromURL.as_view(), name='part-image-download'), # Any other URLs go to the part detail page - url(r'^.*$', views.PartDetail.as_view(), name='part-detail'), + re_path(r'^.*$', views.PartDetail.as_view(), name='part-detail'), ] category_parameter_urls = [ - url(r'^new/', views.CategoryParameterTemplateCreate.as_view(), name='category-param-template-create'), - url(r'^(?P\d+)/edit/', views.CategoryParameterTemplateEdit.as_view(), name='category-param-template-edit'), - url(r'^(?P\d+)/delete/', views.CategoryParameterTemplateDelete.as_view(), name='category-param-template-delete'), + re_path(r'^new/', views.CategoryParameterTemplateCreate.as_view(), name='category-param-template-create'), + re_path(r'^(?P\d+)/edit/', views.CategoryParameterTemplateEdit.as_view(), name='category-param-template-edit'), + re_path(r'^(?P\d+)/delete/', views.CategoryParameterTemplateDelete.as_view(), name='category-param-template-delete'), ] category_urls = [ # Top level subcategory display - url(r'^subcategory/', views.PartIndex.as_view(template_name='part/subcategory.html'), name='category-index-subcategory'), + re_path(r'^subcategory/', views.PartIndex.as_view(template_name='part/subcategory.html'), name='category-index-subcategory'), # Category detail views - url(r'(?P\d+)/', include([ - url(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'), - url(r'^parameters/', include(category_parameter_urls)), + re_path(r'(?P\d+)/', include([ + re_path(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'), + re_path(r'^parameters/', include(category_parameter_urls)), # Anything else - url(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'), + re_path(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'), ])) ] @@ -62,27 +62,27 @@ category_urls = [ part_urls = [ # Upload a part - url(r'^import/', views.PartImport.as_view(), name='part-import'), - url(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'), + re_path(r'^import/', views.PartImport.as_view(), name='part-import'), + re_path(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'), # Download a BOM upload template - url(r'^bom_template/?', views.BomUploadTemplate.as_view(), name='bom-upload-template'), + re_path(r'^bom_template/?', views.BomUploadTemplate.as_view(), name='bom-upload-template'), # Individual part using pk - url(r'^(?P\d+)/', include(part_detail_urls)), + re_path(r'^(?P\d+)/', include(part_detail_urls)), # Part category - url(r'^category/', include(category_urls)), + re_path(r'^category/', include(category_urls)), # Part parameters - url(r'^parameter/', include(part_parameter_urls)), + re_path(r'^parameter/', include(part_parameter_urls)), # Change category for multiple parts - url(r'^set-category/?', views.PartSetCategory.as_view(), name='part-set-category'), + re_path(r'^set-category/?', views.PartSetCategory.as_view(), name='part-set-category'), # Individual part using IPN as slug - url(r'^(?P[-\w]+)/', views.PartDetailFromIPN.as_view(), name='part-detail-from-ipn'), + re_path(r'^(?P[-\w]+)/', views.PartDetailFromIPN.as_view(), name='part-detail-from-ipn'), # Top level part list (display top level parts and categories) - url(r'^.*$', views.PartIndex.as_view(), name='part-index'), + re_path(r'^.*$', views.PartIndex.as_view(), name='part-index'), ] diff --git a/InvenTree/plugin/api.py b/InvenTree/plugin/api.py index 5a4ea7bae3..5c8c1b3e72 100644 --- a/InvenTree/plugin/api.py +++ b/InvenTree/plugin/api.py @@ -5,7 +5,7 @@ JSON API for the plugin app # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.conf.urls import url, include +from django.urls import include, re_path from rest_framework import generics from rest_framework import status @@ -118,18 +118,18 @@ class PluginSettingDetail(generics.RetrieveUpdateAPIView): plugin_api_urls = [ # Plugin settings URLs - url(r'^settings/', include([ - url(r'^(?P\d+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), - url(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), + re_path(r'^settings/', include([ + re_path(r'^(?P\d+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), + re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), ])), # Detail views for a single PluginConfig item - url(r'^(?P\d+)/', include([ - url(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), ])), - url(r'^install/', PluginInstall.as_view(), name='api-plugin-install'), + re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'), # Anything else - url(r'^.*$', PluginList.as_view(), name='api-plugin-list'), + re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'), ] diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 18c1afe64a..62ce38a673 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -6,7 +6,7 @@ import logging import json import requests -from django.conf.urls import url, include +from django.urls import include, re_path from django.db.utils import OperationalError, ProgrammingError from plugin.models import PluginConfig, PluginSetting @@ -303,7 +303,7 @@ class UrlsMixin: Urlpatterns for this plugin """ if self.has_urls: - return url(f'^{self.slug}/', include((self.urls, self.slug)), name=self.slug) + return re_path(f'^{self.slug}/', include((self.urls, self.slug)), name=self.slug) return None @property diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index a05e804def..ac6f14c3e3 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -6,8 +6,7 @@ from plugin import IntegrationPluginBase from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin from django.http import HttpResponse -from django.utils.translation import ugettext_lazy as _ -from django.conf.urls import url, include +from django.urls import include, re_path class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixin, IntegrationPluginBase): diff --git a/InvenTree/plugin/urls.py b/InvenTree/plugin/urls.py index d41a84e2f1..08f547aca2 100644 --- a/InvenTree/plugin/urls.py +++ b/InvenTree/plugin/urls.py @@ -2,7 +2,7 @@ URL lookup for plugin app """ -from django.conf.urls import url, include +from django.urls import include, re_path from plugin import registry @@ -21,4 +21,4 @@ def get_plugin_urls(): if plugin.mixin_enabled('urls'): urls.append(plugin.urlpatterns) - return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin'))) + return re_path(f'^{PLUGIN_BASE}/', include((urls, 'plugin'))) diff --git a/InvenTree/report/api.py b/InvenTree/report/api.py index 0484cfbc06..8e58ab0c5f 100644 --- a/InvenTree/report/api.py +++ b/InvenTree/report/api.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ -from django.conf.urls import url, include +from django.urls import include, path, re_path from django.core.exceptions import ValidationError, FieldError from django.http import HttpResponse @@ -730,62 +729,62 @@ class SalesOrderReportPrint(generics.RetrieveAPIView, OrderReportMixin, ReportPr report_api_urls = [ # Purchase order reports - url(r'po/', include([ + re_path(r'po/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/', PurchaseOrderReportPrint.as_view(), name='api-po-report-print'), - url(r'^$', PurchaseOrderReportDetail.as_view(), name='api-po-report-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/', PurchaseOrderReportPrint.as_view(), name='api-po-report-print'), + path('', PurchaseOrderReportDetail.as_view(), name='api-po-report-detail'), ])), # List view - url(r'^$', PurchaseOrderReportList.as_view(), name='api-po-report-list'), + path('', PurchaseOrderReportList.as_view(), name='api-po-report-list'), ])), # Sales order reports - url(r'so/', include([ + re_path(r'so/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/', SalesOrderReportPrint.as_view(), name='api-so-report-print'), - url(r'^$', SalesOrderReportDetail.as_view(), name='api-so-report-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/', SalesOrderReportPrint.as_view(), name='api-so-report-print'), + path('', SalesOrderReportDetail.as_view(), name='api-so-report-detail'), ])), - url(r'^$', SalesOrderReportList.as_view(), name='api-so-report-list'), + path('', SalesOrderReportList.as_view(), name='api-so-report-list'), ])), # Build reports - url(r'build/', include([ + re_path(r'build/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/?', BuildReportPrint.as_view(), name='api-build-report-print'), - url(r'^.$', BuildReportDetail.as_view(), name='api-build-report-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/?', BuildReportPrint.as_view(), name='api-build-report-print'), + re_path(r'^.$', BuildReportDetail.as_view(), name='api-build-report-detail'), ])), # List view - url(r'^.*$', BuildReportList.as_view(), name='api-build-report-list'), + re_path(r'^.*$', BuildReportList.as_view(), name='api-build-report-list'), ])), # Bill of Material reports - url(r'bom/', include([ + re_path(r'bom/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/?', BOMReportPrint.as_view(), name='api-bom-report-print'), - url(r'^.*$', BOMReportDetail.as_view(), name='api-bom-report-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/?', BOMReportPrint.as_view(), name='api-bom-report-print'), + re_path(r'^.*$', BOMReportDetail.as_view(), name='api-bom-report-detail'), ])), # List view - url(r'^.*$', BOMReportList.as_view(), name='api-bom-report-list'), + re_path(r'^.*$', BOMReportList.as_view(), name='api-bom-report-list'), ])), # Stock item test reports - url(r'test/', include([ + re_path(r'test/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/?', StockItemTestReportPrint.as_view(), name='api-stockitem-testreport-print'), - url(r'^.*$', StockItemTestReportDetail.as_view(), name='api-stockitem-testreport-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/?', StockItemTestReportPrint.as_view(), name='api-stockitem-testreport-print'), + re_path(r'^.*$', StockItemTestReportDetail.as_view(), name='api-stockitem-testreport-detail'), ])), # List view - url(r'^.*$', StockItemTestReportList.as_view(), name='api-stockitem-testreport-list'), + re_path(r'^.*$', StockItemTestReportList.as_view(), name='api-stockitem-testreport-list'), ])), ] diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 52c159a7ff..2e2b89bb33 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -9,7 +9,7 @@ from collections import OrderedDict from datetime import datetime, timedelta from django.core.exceptions import ValidationError as DjangoValidationError -from django.conf.urls import url, include +from django.urls import include, path, re_path from django.http import JsonResponse from django.db.models import Q, F from django.db import transaction @@ -1383,47 +1383,47 @@ class LocationDetail(generics.RetrieveUpdateDestroyAPIView): stock_api_urls = [ - url(r'^location/', include([ + re_path(r'^location/', include([ - url(r'^tree/', StockLocationTree.as_view(), name='api-location-tree'), + re_path(r'^tree/', StockLocationTree.as_view(), name='api-location-tree'), - url(r'^(?P\d+)/', LocationDetail.as_view(), name='api-location-detail'), - url(r'^.*$', StockLocationList.as_view(), name='api-location-list'), + re_path(r'^(?P\d+)/', LocationDetail.as_view(), name='api-location-detail'), + re_path(r'^.*$', StockLocationList.as_view(), name='api-location-list'), ])), # Endpoints for bulk stock adjustment actions - url(r'^count/', StockCount.as_view(), name='api-stock-count'), - url(r'^add/', StockAdd.as_view(), name='api-stock-add'), - url(r'^remove/', StockRemove.as_view(), name='api-stock-remove'), - url(r'^transfer/', StockTransfer.as_view(), name='api-stock-transfer'), - url(r'^assign/', StockAssign.as_view(), name='api-stock-assign'), - url(r'^merge/', StockMerge.as_view(), name='api-stock-merge'), + 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'), # StockItemAttachment API endpoints - url(r'^attachment/', include([ - url(r'^(?P\d+)/', StockAttachmentDetail.as_view(), name='api-stock-attachment-detail'), - url(r'^$', StockAttachmentList.as_view(), name='api-stock-attachment-list'), + re_path(r'^attachment/', include([ + re_path(r'^(?P\d+)/', StockAttachmentDetail.as_view(), name='api-stock-attachment-detail'), + path('', StockAttachmentList.as_view(), name='api-stock-attachment-list'), ])), # StockItemTestResult API endpoints - url(r'^test/', include([ - url(r'^(?P\d+)/', StockItemTestResultDetail.as_view(), name='api-stock-test-result-detail'), - url(r'^.*$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'), + re_path(r'^test/', include([ + re_path(r'^(?P\d+)/', StockItemTestResultDetail.as_view(), name='api-stock-test-result-detail'), + re_path(r'^.*$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'), ])), # StockItemTracking API endpoints - url(r'^track/', include([ - url(r'^(?P\d+)/', StockTrackingDetail.as_view(), name='api-stock-tracking-detail'), - url(r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'), + re_path(r'^track/', include([ + re_path(r'^(?P\d+)/', StockTrackingDetail.as_view(), name='api-stock-tracking-detail'), + re_path(r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'), ])), # Detail views for a single stock item - url(r'^(?P\d+)/', include([ - url(r'^serialize/', StockItemSerialize.as_view(), name='api-stock-item-serialize'), - url(r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'), - url(r'^.*$', StockDetail.as_view(), name='api-stock-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^serialize/', StockItemSerialize.as_view(), name='api-stock-item-serialize'), + re_path(r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'), + re_path(r'^.*$', StockDetail.as_view(), name='api-stock-detail'), ])), # Anything else - url(r'^.*$', StockList.as_view(), name='api-stock-list'), + re_path(r'^.*$', StockList.as_view(), name='api-stock-list'), ] diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index bb4a56e2dc..11ad145d08 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -2,55 +2,55 @@ URL lookup for Stock app """ -from django.conf.urls import url, include +from django.urls import include, re_path from stock import views location_urls = [ - url(r'^(?P\d+)/', include([ - url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'), - url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'), + re_path(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'), # Anything else - url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'), + re_path('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'), ])), ] stock_item_detail_urls = [ - url(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'), - url(r'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'), - url(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'), - url(r'^delete_test_data/', views.StockItemDeleteTestData.as_view(), name='stock-item-delete-test-data'), - url(r'^return/', views.StockItemReturnToStock.as_view(), name='stock-item-return'), + re_path(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'), + re_path(r'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'), + re_path(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'), + re_path(r'^delete_test_data/', views.StockItemDeleteTestData.as_view(), name='stock-item-delete-test-data'), + re_path(r'^return/', views.StockItemReturnToStock.as_view(), name='stock-item-return'), - url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'), + re_path(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'), - url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'), + re_path('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'), ] stock_tracking_urls = [ # edit - url(r'^(?P\d+)/edit/', views.StockItemTrackingEdit.as_view(), name='stock-tracking-edit'), + re_path(r'^(?P\d+)/edit/', views.StockItemTrackingEdit.as_view(), name='stock-tracking-edit'), # delete - url(r'^(?P\d+)/delete', views.StockItemTrackingDelete.as_view(), name='stock-tracking-delete'), + re_path(r'^(?P\d+)/delete', views.StockItemTrackingDelete.as_view(), name='stock-tracking-delete'), ] stock_urls = [ # Stock location - url(r'^location/', include(location_urls)), + re_path(r'^location/', include(location_urls)), - url(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'), + re_path(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'), - url(r'^track/', include(stock_tracking_urls)), + re_path(r'^track/', include(stock_tracking_urls)), # Individual stock items - url(r'^item/(?P\d+)/', include(stock_item_detail_urls)), + re_path(r'^item/(?P\d+)/', include(stock_item_detail_urls)), - url(r'^sublocations/', views.StockIndex.as_view(template_name='stock/sublocation.html'), name='stock-sublocations'), + re_path(r'^sublocations/', views.StockIndex.as_view(template_name='stock/sublocation.html'), name='stock-sublocations'), - url(r'^.*$', views.StockIndex.as_view(), name='stock-index'), + re_path(r'^.*$', views.StockIndex.as_view(), name='stock-index'), ] diff --git a/InvenTree/users/api.py b/InvenTree/users/api.py index 0e62af4dbe..47e073fb52 100644 --- a/InvenTree/users/api.py +++ b/InvenTree/users/api.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist -from django.conf.urls import url, include +from django.urls import include, path, re_path from django_filters.rest_framework import DjangoFilterBackend @@ -174,14 +174,14 @@ class GetAuthToken(APIView): user_urls = [ - url(r'roles/?$', RoleDetails.as_view(), name='api-user-roles'), - url(r'token/?$', GetAuthToken.as_view(), name='api-token'), + re_path(r'roles/?$', RoleDetails.as_view(), name='api-user-roles'), + re_path(r'token/?$', GetAuthToken.as_view(), name='api-token'), - url(r'^owner/', include([ - url(r'^(?P[0-9]+)/$', OwnerDetail.as_view(), name='api-owner-detail'), - url(r'^.*$', OwnerList.as_view(), name='api-owner-list'), + re_path(r'^owner/', include([ + path('/', OwnerDetail.as_view(), name='api-owner-detail'), + re_path(r'^.*$', OwnerList.as_view(), name='api-owner-list'), ])), - url(r'^(?P[0-9]+)/?$', UserDetail.as_view(), name='user-detail'), - url(r'^$', UserList.as_view()), + re_path(r'^(?P[0-9]+)/?$', UserDetail.as_view(), name='user-detail'), + path('', UserList.as_view()), ] From de6507e9180001f764014e7e42a736311ccfeb4c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 22:03:49 +0200 Subject: [PATCH 3/6] update translation commands --- InvenTree/InvenTree/api.py | 2 +- InvenTree/InvenTree/fields.py | 2 +- InvenTree/InvenTree/forms.py | 2 +- InvenTree/InvenTree/helpers.py | 2 +- InvenTree/InvenTree/serializers.py | 2 +- InvenTree/InvenTree/status.py | 2 +- InvenTree/InvenTree/status_codes.py | 2 +- InvenTree/build/forms.py | 2 +- InvenTree/build/models.py | 2 +- InvenTree/build/serializers.py | 2 +- InvenTree/build/tasks.py | 2 +- InvenTree/build/views.py | 2 +- InvenTree/common/models.py | 2 +- InvenTree/common/views.py | 2 +- InvenTree/company/forms.py | 2 +- InvenTree/company/models.py | 2 +- InvenTree/company/serializers.py | 2 +- InvenTree/company/views.py | 2 +- InvenTree/label/api.py | 2 +- InvenTree/order/forms.py | 2 +- InvenTree/order/models.py | 2 +- InvenTree/order/serializers.py | 2 +- InvenTree/order/views.py | 2 +- InvenTree/part/api.py | 2 +- InvenTree/part/forms.py | 2 +- InvenTree/part/serializers.py | 2 +- InvenTree/part/tasks.py | 2 +- InvenTree/part/templatetags/inventree_extras.py | 2 +- InvenTree/plugin/apps.py | 2 +- InvenTree/plugin/events.py | 2 +- InvenTree/plugin/integration.py | 2 +- InvenTree/plugin/samples/integration/sample.py | 1 + InvenTree/plugin/serializers.py | 2 +- InvenTree/report/api.py | 1 + InvenTree/stock/api.py | 2 +- InvenTree/stock/forms.py | 2 +- InvenTree/stock/serializers.py | 2 +- InvenTree/stock/views.py | 2 +- InvenTree/users/admin.py | 2 +- 39 files changed, 39 insertions(+), 37 deletions(-) diff --git a/InvenTree/InvenTree/api.py b/InvenTree/InvenTree/api.py index 09ec02f158..171fe414d2 100644 --- a/InvenTree/InvenTree/api.py +++ b/InvenTree/InvenTree/api.py @@ -5,7 +5,7 @@ Main JSON interface views # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.conf import settings from django.http import JsonResponse diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py index fa91831679..c6efb687f1 100644 --- a/InvenTree/InvenTree/fields.py +++ b/InvenTree/InvenTree/fields.py @@ -6,7 +6,7 @@ import sys from .validators import allowable_url_schemes -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.forms.fields import URLField as FormURLField from django.db import models as models diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index dd40e54d9c..36ad66de24 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from urllib.parse import urlencode import logging -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django import forms from django.contrib.auth.models import User, Group from django.conf import settings diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 1258fffe61..d9dfaa395d 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -13,7 +13,7 @@ from decimal import Decimal, InvalidOperation from wsgiref.util import FileWrapper from django.http import StreamingHttpResponse from django.core.exceptions import ValidationError, FieldError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.contrib.auth.models import Permission diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py index e21e2fb0fc..3e57883875 100644 --- a/InvenTree/InvenTree/serializers.py +++ b/InvenTree/InvenTree/serializers.py @@ -15,7 +15,7 @@ from collections import OrderedDict from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ValidationError as DjangoValidationError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.db import models from djmoney.contrib.django_rest_framework.fields import MoneyField diff --git a/InvenTree/InvenTree/status.py b/InvenTree/InvenTree/status.py index 181f431574..39b0afc57d 100644 --- a/InvenTree/InvenTree/status.py +++ b/InvenTree/InvenTree/status.py @@ -3,7 +3,7 @@ Provides system status functionality checks. """ # -*- coding: utf-8 -*- -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.utils import timezone import logging diff --git a/InvenTree/InvenTree/status_codes.py b/InvenTree/InvenTree/status_codes.py index 93f213445c..57bacc861e 100644 --- a/InvenTree/InvenTree/status_codes.py +++ b/InvenTree/InvenTree/status_codes.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class StatusCode: diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py index eaae0636c9..08714b0f3c 100644 --- a/InvenTree/build/forms.py +++ b/InvenTree/build/forms.py @@ -6,7 +6,7 @@ Django Forms for interacting with Build objects from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django import forms from InvenTree.forms import HelperForm diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 3edced5ffe..1fdf613b68 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -18,7 +18,7 @@ from django.db.models.functions import Coalesce from django.db.models.signals import post_save from django.dispatch.dispatcher import receiver from django.urls import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from markdownx.models import MarkdownxField diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index d037ad546e..07a0bcc29a 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from django.db import transaction from django.core.exceptions import ValidationError as DjangoValidationError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.db.models import Case, When, Value from django.db.models import BooleanField diff --git a/InvenTree/build/tasks.py b/InvenTree/build/tasks.py index 6752bc5501..b69057d444 100644 --- a/InvenTree/build/tasks.py +++ b/InvenTree/build/tasks.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals from decimal import Decimal import logging -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string from allauth.account.models import EmailAddress diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index 37fb024940..2b8629afe9 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -5,7 +5,7 @@ Django views for interacting with Build objects # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from .models import Build diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 89febf3713..9dac93d28e 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -33,7 +33,7 @@ from djmoney.contrib.exchange.exceptions import MissingRate from rest_framework.exceptions import PermissionDenied -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.core.validators import MinValueValidator, URLValidator from django.core.exceptions import ValidationError diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index 4b8310ddd2..7fae6f3710 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import os -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.conf import settings from django.core.files.storage import FileSystemStorage diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index 506133df00..5549f66222 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -8,7 +8,7 @@ from __future__ import unicode_literals from InvenTree.forms import HelperForm from InvenTree.fields import RoundingDecimalFormField -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ import django.forms from .models import Company diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 214f1cd605..fff38a8e99 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import os -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.core.validators import MinValueValidator from django.core.exceptions import ValidationError diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 736e379c8a..236dcc15db 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -2,7 +2,7 @@ JSON serializers for Company app """ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py index f3a9af7628..8c23002800 100644 --- a/InvenTree/company/views.py +++ b/InvenTree/company/views.py @@ -6,7 +6,7 @@ Django views for interacting with Company app # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.urls import reverse diff --git a/InvenTree/label/api.py b/InvenTree/label/api.py index 5103d99676..790e115771 100644 --- a/InvenTree/label/api.py +++ b/InvenTree/label/api.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals from io import BytesIO from PIL import Image -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.conf import settings from django.conf.urls import url, include diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 33044d8440..d6b99b7fd9 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -6,7 +6,7 @@ Django Forms for interacting with Order objects from __future__ import unicode_literals from django import forms -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from InvenTree.forms import HelperForm from InvenTree.fields import InvenTreeMoneyField diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 63862078f6..2b722ddecd 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -17,7 +17,7 @@ from django.core.validators import MinValueValidator from django.core.exceptions import ValidationError from django.contrib.auth.models import User from django.urls import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from markdownx.models import MarkdownxField from mptt.models import TreeForeignKey diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 98b204612e..a608cf3355 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from decimal import Decimal -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError as DjangoValidationError from django.db import models, transaction diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 69d42b9594..35f8b973f4 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -11,7 +11,7 @@ from django.http.response import JsonResponse from django.shortcuts import get_object_or_404 from django.urls import reverse from django.http import HttpResponseRedirect -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.forms import HiddenInput, IntegerField diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index b2acaf678e..ca9accf9e2 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -11,7 +11,7 @@ from django.urls import include, path, re_path from django.http import JsonResponse from django.db.models import Q, F, Count, Min, Max, Avg from django.db import transaction -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status from rest_framework.response import Response diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 8925c6d9bd..2ba60d111b 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -6,7 +6,7 @@ Django Forms for interacting with Part objects from __future__ import unicode_literals from django import forms -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from mptt.fields import TreeNodeChoiceField diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 0e865ea74b..098c1d1aea 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -11,7 +11,7 @@ from django.db.models import ExpressionWrapper, F, Q, Func from django.db.models import Subquery, OuterRef, FloatField from django.db.models.functions import Coalesce -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from sql_util.utils import SubqueryCount, SubquerySum diff --git a/InvenTree/part/tasks.py b/InvenTree/part/tasks.py index b5e02e1128..b158d26ad3 100644 --- a/InvenTree/part/tasks.py +++ b/InvenTree/part/tasks.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import logging -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ import InvenTree.helpers import InvenTree.tasks diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 889946ff19..3eba8368af 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -12,7 +12,7 @@ import logging from django.utils.html import format_html -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.conf import settings as djangosettings from django import template diff --git a/InvenTree/plugin/apps.py b/InvenTree/plugin/apps.py index c611f6f8c1..8de4cb9b6c 100644 --- a/InvenTree/plugin/apps.py +++ b/InvenTree/plugin/apps.py @@ -5,7 +5,7 @@ import logging from django.apps import AppConfig from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from maintenance_mode.core import set_maintenance_mode diff --git a/InvenTree/plugin/events.py b/InvenTree/plugin/events.py index b510b42683..4948366bfa 100644 --- a/InvenTree/plugin/events.py +++ b/InvenTree/plugin/events.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import logging -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.conf import settings from django.db import transaction diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index 7797134b14..cab3e81a8b 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -11,7 +11,7 @@ import pathlib from django.urls.base import reverse from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ import plugin.plugin as plugin_base from plugin.helpers import get_git_log, GitStatus diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index ac6f14c3e3..b849092bad 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -6,6 +6,7 @@ from plugin import IntegrationPluginBase from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin from django.http import HttpResponse +from django.utils.translation import gettext_lazy as _ from django.urls import include, re_path diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index 6965f398f0..7a76c48067 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -10,7 +10,7 @@ import subprocess from django.core.exceptions import ValidationError from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.utils import timezone from rest_framework import serializers diff --git a/InvenTree/report/api.py b/InvenTree/report/api.py index 8e58ab0c5f..8a063001a6 100644 --- a/InvenTree/report/api.py +++ b/InvenTree/report/api.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django.utils.translation import gettext_lazy as _ from django.urls import include, path, re_path from django.core.exceptions import ValidationError, FieldError from django.http import HttpResponse diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 2e2b89bb33..0c0dafbf41 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -13,7 +13,7 @@ from django.urls import include, path, re_path from django.http import JsonResponse from django.db.models import Q, F from django.db import transaction -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django_filters.rest_framework import DjangoFilterBackend from django_filters import rest_framework as rest_filters diff --git a/InvenTree/stock/forms.py b/InvenTree/stock/forms.py index ef65b25cd9..3860936ae7 100644 --- a/InvenTree/stock/forms.py +++ b/InvenTree/stock/forms.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from django import forms from django.forms.utils import ErrorDict -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from mptt.fields import TreeNodeChoiceField diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 941219da6c..a263700a41 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -10,7 +10,7 @@ from datetime import datetime, timedelta from django.db import transaction from django.core.exceptions import ValidationError as DjangoValidationError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.db.models.functions import Coalesce from django.db.models import Case, When, Value from django.db.models import BooleanField diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index b0661dd0e3..3bca77ec9e 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -15,7 +15,7 @@ from django.http import HttpResponseRedirect from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from moneyed import CURRENCIES diff --git a/InvenTree/users/admin.py b/InvenTree/users/admin.py index 39a7b1c9ee..9763644479 100644 --- a/InvenTree/users/admin.py +++ b/InvenTree/users/admin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.contrib import admin, messages from django import forms From e7a0cf7342bbbd24d268f7257b5723e2f9e0a493 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 22:04:37 +0200 Subject: [PATCH 4/6] fix old url() usage --- InvenTree/InvenTree/middleware.py | 4 +-- InvenTree/label/api.py | 32 +++++++++---------- InvenTree/plugin/registry.py | 6 ++-- .../plugin/samples/integration/sample.py | 8 ++--- InvenTree/plugin/test_integration.py | 6 ++-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index 0ec1d4e6c5..91cfefc6d6 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -1,7 +1,7 @@ from django.shortcuts import HttpResponseRedirect from django.urls import reverse_lazy, Resolver404 from django.shortcuts import redirect -from django.conf.urls import include, url +from django.urls import include, re_path from django.conf import settings from django.contrib.auth.middleware import PersistentRemoteUserMiddleware @@ -92,7 +92,7 @@ class AuthRequiredMiddleware(object): return response -url_matcher = url('', include(frontendpatterns)) +url_matcher = re_path('', include(frontendpatterns)) class Check2FAMiddleware(BaseRequire2FAMiddleware): diff --git a/InvenTree/label/api.py b/InvenTree/label/api.py index 790e115771..b580853b65 100644 --- a/InvenTree/label/api.py +++ b/InvenTree/label/api.py @@ -7,7 +7,7 @@ from PIL import Image from django.utils.translation import gettext_lazy as _ from django.conf import settings -from django.conf.urls import url, include +from django.urls import include, re_path from django.core.exceptions import ValidationError, FieldError from django.http import HttpResponse, JsonResponse @@ -579,38 +579,38 @@ class PartLabelPrint(generics.RetrieveAPIView, PartLabelMixin, LabelPrintMixin): label_api_urls = [ # Stock item labels - url(r'stock/', include([ + re_path(r'stock/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/?', StockItemLabelPrint.as_view(), name='api-stockitem-label-print'), - url(r'^.*$', StockItemLabelDetail.as_view(), name='api-stockitem-label-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/?', StockItemLabelPrint.as_view(), name='api-stockitem-label-print'), + re_path(r'^.*$', StockItemLabelDetail.as_view(), name='api-stockitem-label-detail'), ])), # List view - url(r'^.*$', StockItemLabelList.as_view(), name='api-stockitem-label-list'), + re_path(r'^.*$', StockItemLabelList.as_view(), name='api-stockitem-label-list'), ])), # Stock location labels - url(r'location/', include([ + re_path(r'location/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'print/?', StockLocationLabelPrint.as_view(), name='api-stocklocation-label-print'), - url(r'^.*$', StockLocationLabelDetail.as_view(), name='api-stocklocation-label-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'print/?', StockLocationLabelPrint.as_view(), name='api-stocklocation-label-print'), + re_path(r'^.*$', StockLocationLabelDetail.as_view(), name='api-stocklocation-label-detail'), ])), # List view - url(r'^.*$', StockLocationLabelList.as_view(), name='api-stocklocation-label-list'), + re_path(r'^.*$', StockLocationLabelList.as_view(), name='api-stocklocation-label-list'), ])), # Part labels - url(r'^part/', include([ + re_path(r'^part/', include([ # Detail views - url(r'^(?P\d+)/', include([ - url(r'^print/', PartLabelPrint.as_view(), name='api-part-label-print'), - url(r'^.*$', PartLabelDetail.as_view(), name='api-part-label-detail'), + re_path(r'^(?P\d+)/', include([ + re_path(r'^print/', PartLabelPrint.as_view(), name='api-part-label-print'), + re_path(r'^.*$', PartLabelDetail.as_view(), name='api-part-label-detail'), ])), # List view - url(r'^.*$', PartLabelList.as_view(), name='api-part-label-list'), + re_path(r'^.*$', PartLabelList.as_view(), name='api-part-label-list'), ])), ] diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 3276c82f45..304932f6f8 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -17,7 +17,7 @@ from importlib import reload from django.apps import apps from django.conf import settings from django.db.utils import OperationalError, ProgrammingError, IntegrityError -from django.conf.urls import url, include +from django.urls import include, re_path from django.urls import clear_url_caches from django.contrib import admin from django.utils.text import slugify @@ -570,12 +570,12 @@ class PluginsRegistry: for index, a in enumerate(urlpatterns): if hasattr(a, 'app_name'): if a.app_name == 'admin': - urlpatterns[index] = url(r'^admin/', admin.site.urls, name='inventree-admin') + urlpatterns[index] = re_path(r'^admin/', admin.site.urls, name='inventree-admin') elif a.app_name == 'plugin': urlpatterns[index] = get_plugin_urls() # replace frontendpatterns - global_pattern[0] = url('', include(urlpatterns)) + global_pattern[0] = re_path('', include(urlpatterns)) clear_url_caches() def _reload_apps(self, force_reload: bool = False): diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index b849092bad..2df3bc116a 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -28,13 +28,13 @@ class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixi def setup_urls(self): he_urls = [ - url(r'^he/', self.view_test, name='he'), - url(r'^ha/', self.view_test, name='ha'), + re_path(r'^he/', self.view_test, name='he'), + re_path(r'^ha/', self.view_test, name='ha'), ] return [ - url(r'^hi/', self.view_test, name='hi'), - url(r'^ho/', include(he_urls), name='ho'), + re_path(r'^hi/', self.view_test, name='hi'), + re_path(r'^ho/', include(he_urls), name='ho'), ] SETTINGS = { diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index dbc77f7cd0..3e4c38f968 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -2,7 +2,7 @@ from django.test import TestCase from django.conf import settings -from django.conf.urls import url, include +from django.urls import include, re_path from django.contrib.auth import get_user_model from datetime import datetime @@ -66,7 +66,7 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase): class UrlsCls(UrlsMixin, IntegrationPluginBase): def test(): return 'ccc' - URLS = [url('testpath', test, name='test'), ] + URLS = [re_path('testpath', test, name='test'), ] self.mixin = UrlsCls() class NoUrlsCls(UrlsMixin, IntegrationPluginBase): @@ -81,7 +81,7 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase): self.assertEqual(self.mixin.base_url, target_url) # urlpattern - target_pattern = url(f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name) + target_pattern = re_path(f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name) self.assertEqual(self.mixin.urlpatterns.reverse_dict, target_pattern.reverse_dict) # resolve the view From 96e6752324d07da6cd909e3dfa7e93a6f1079972 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 22:13:35 +0200 Subject: [PATCH 5/6] remove double import --- InvenTree/InvenTree/urls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index e50a64a988..aefed5156b 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -5,7 +5,6 @@ Passes URL lookup downstream to each app as required. """ from django.urls import include, path, re_path -from django.urls import path from django.contrib import admin from company.urls import company_urls From 105818dd0d29fd3e2d810f74db66784cc559fcc9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 May 2022 22:44:36 +0200 Subject: [PATCH 6/6] Add docs about target versions and upgrades --- CONTRIBUTING.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0677e61de4..82cfa4e9e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,31 @@ The HEAD of the "stable" branch represents the latest stable release code. - When approved, the branch is merged back *into* stable, with an incremented PATCH number (e.g. 0.4.1 -> 0.4.2) - The bugfix *must* also be cherry picked into the *master* branch. +## Environment +#### Target version +We are currently targeting: +| Name | Minimum version | +|---|---| +| Python | 3.9 | +| Django | 3.2 | + +### Auto creating updates +The following tools can be used to auto-upgrade syntax that was depreciated in new versions: +```bash +pip install pyupgrade +pip install django-upgrade +``` + +To update the codebase run the following script. +```bash +pyupgrade `find . -name "*.py"` +django-upgrade --target-version 3.2 `find . -name "*.py"` +``` + +### Credits +If you add any new dependencies / libraries, they need to be added to [the docs](https://github.com/inventree/inventree-docs/blob/master/docs/credits.md). Please try to do that as timely as possible. + + ## Migration Files Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `invoke migrate` and commit the migration files before submitting the PR.