2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-03-11 22:54:17 +00:00

!refactor(backend): remove legacy metadata endpoints (#11111)

* !refactor(backend): remove legacy metadata endpoints

* add changelog

* fix indent

* remove legacy test
This commit is contained in:
Matthias Mair
2026-02-28 23:12:35 +01:00
committed by GitHub
parent ca57a1d15b
commit e5def31ec5
9 changed files with 46 additions and 267 deletions

View File

@@ -10,8 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Breaking Changes - Remove deprecated features and APIs
- [#11111](https://github.com/inventree/InvenTree/pull/11111) - removes legacy metadata APIs
- [#9814](https://github.com/inventree/InvenTree/pull/9814) - removes legacy config path support
## Unreleased - YYYY-MM-DD
### Breaking Changes

View File

@@ -24,7 +24,7 @@ from build.models import Build, BuildItem, BuildLine
from build.status_codes import BuildStatus, BuildStatusGroups
from data_exporter.mixins import DataExportViewMixin
from generic.states.api import StatusView
from InvenTree.api import BulkDeleteMixin, ParameterListMixin, meta_path
from InvenTree.api import BulkDeleteMixin, ParameterListMixin
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import (
SEARCH_ORDER_FILTER_ALIAS,
@@ -994,13 +994,7 @@ build_api_urls = [
path(
'item/',
include([
path(
'<int:pk>/',
include([
meta_path(BuildItem),
path('', BuildItemDetail.as_view(), name='api-build-item-detail'),
]),
),
path('<int:pk>/', BuildItemDetail.as_view(), name='api-build-item-detail'),
path('', BuildItemList.as_view(), name='api-build-item-list'),
]),
),
@@ -1040,7 +1034,6 @@ build_api_urls = [
path('finish/', BuildFinish.as_view(), name='api-build-finish'),
path('cancel/', BuildCancel.as_view(), name='api-build-cancel'),
path('unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
meta_path(Build),
path('', BuildDetail.as_view(), name='api-build-detail'),
]),
),

View File

@@ -46,7 +46,6 @@ from InvenTree.api import (
BulkDeleteMixin,
GenericMetadataView,
SimpleGenericMetadataView,
meta_path,
)
from InvenTree.config import CONFIG_LOOKUPS
from InvenTree.filters import (
@@ -1407,13 +1406,7 @@ common_api_urls = [
path(
'attachment/',
include([
path(
'<int:pk>/',
include([
meta_path(common.models.Attachment),
path('', AttachmentDetail.as_view(), name='api-attachment-detail'),
]),
),
path('<int:pk>/', AttachmentDetail.as_view(), name='api-attachment-detail'),
path('', AttachmentList.as_view(), name='api-attachment-list'),
]),
),
@@ -1426,14 +1419,8 @@ common_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(common.models.ParameterTemplate),
path(
'',
ParameterTemplateDetail.as_view(),
name='api-parameter-template-detail',
),
]),
ParameterTemplateDetail.as_view(),
name='api-parameter-template-detail',
),
path(
'',
@@ -1442,13 +1429,7 @@ common_api_urls = [
),
]),
),
path(
'<int:pk>/',
include([
meta_path(common.models.Parameter),
path('', ParameterDetail.as_view(), name='api-parameter-detail'),
]),
),
path('<int:pk>/', ParameterDetail.as_view(), name='api-parameter-detail'),
path('', ParameterList.as_view(), name='api-parameter-list'),
]),
),
@@ -1480,13 +1461,7 @@ common_api_urls = [
'project-code/',
include([
path(
'<int:pk>/',
include([
meta_path(common.models.ProjectCode),
path(
'', ProjectCodeDetail.as_view(), name='api-project-code-detail'
),
]),
'<int:pk>/', ProjectCodeDetail.as_view(), name='api-project-code-detail'
),
path('', ProjectCodeList.as_view(), name='api-project-code-list'),
]),

View File

@@ -9,7 +9,7 @@ from django_filters.rest_framework.filterset import FilterSet
import part.models
from data_exporter.mixins import DataExportViewMixin
from InvenTree.api import ListCreateDestroyAPIView, ParameterListMixin, meta_path
from InvenTree.api import ListCreateDestroyAPIView, ParameterListMixin
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS
from InvenTree.mixins import (
@@ -492,29 +492,15 @@ class SupplierPriceBreakDetail(SupplierPriceBreakMixin, RetrieveUpdateDestroyAPI
manufacturer_part_api_urls = [
path(
'<int:pk>/',
include([
meta_path(ManufacturerPart),
path(
'',
ManufacturerPartDetail.as_view(),
name='api-manufacturer-part-detail',
),
]),
ManufacturerPartDetail.as_view(),
name='api-manufacturer-part-detail',
),
# Catch anything else
path('', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'),
]
supplier_part_api_urls = [
path(
'<int:pk>/',
include([
meta_path(SupplierPart),
path('', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
]),
),
# Catch anything else
path('<int:pk>/', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
path('', SupplierPartList.as_view(), name='api-supplier-part-list'),
]
@@ -538,23 +524,11 @@ company_api_urls = [
),
]),
),
path(
'<int:pk>/',
include([
meta_path(Company),
path('', CompanyDetail.as_view(), name='api-company-detail'),
]),
),
path('<int:pk>/', CompanyDetail.as_view(), name='api-company-detail'),
path(
'contact/',
include([
path(
'<int:pk>/',
include([
meta_path(Contact),
path('', ContactDetail.as_view(), name='api-contact-detail'),
]),
),
path('<int:pk>/', ContactDetail.as_view(), name='api-contact-detail'),
path('', ContactList.as_view(), name='api-contact-list'),
]),
),

View File

@@ -28,12 +28,7 @@ import stock.models as stock_models
import stock.serializers as stock_serializers
from data_exporter.mixins import DataExportViewMixin
from generic.states.api import StatusView
from InvenTree.api import (
BulkUpdateMixin,
ListCreateDestroyAPIView,
ParameterListMixin,
meta_path,
)
from InvenTree.api import BulkUpdateMixin, ListCreateDestroyAPIView, ParameterListMixin
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import (
SEARCH_ORDER_FILTER,
@@ -1903,7 +1898,6 @@ order_api_urls = [
name='api-po-complete',
),
path('issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'),
meta_path(models.PurchaseOrder),
path(
'receive/',
PurchaseOrderReceive.as_view(),
@@ -1930,14 +1924,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.PurchaseOrderLineItem),
path(
'',
PurchaseOrderLineItemDetail.as_view(),
name='api-po-line-detail',
),
]),
PurchaseOrderLineItemDetail.as_view(),
name='api-po-line-detail',
),
path('', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'),
]),
@@ -1948,14 +1936,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.PurchaseOrderExtraLine),
path(
'',
PurchaseOrderExtraLineDetail.as_view(),
name='api-po-extra-line-detail',
),
]),
PurchaseOrderExtraLineDetail.as_view(),
name='api-po-extra-line-detail',
),
path(
'', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list'
@@ -1977,7 +1959,6 @@ order_api_urls = [
SalesOrderShipmentComplete.as_view(),
name='api-so-shipment-ship',
),
meta_path(models.SalesOrderShipment),
path(
'',
SalesOrderShipmentDetail.as_view(),
@@ -2014,7 +1995,6 @@ order_api_urls = [
SalesOrderComplete.as_view(),
name='api-so-complete',
),
meta_path(models.SalesOrder),
# SalesOrder detail endpoint
path('', SalesOrderDetail.as_view(), name='api-so-detail'),
]),
@@ -2036,14 +2016,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.SalesOrderLineItem),
path(
'',
SalesOrderLineItemDetail.as_view(),
name='api-so-line-detail',
),
]),
SalesOrderLineItemDetail.as_view(),
name='api-so-line-detail',
),
path('', SalesOrderLineItemList.as_view(), name='api-so-line-list'),
]),
@@ -2054,14 +2028,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.SalesOrderExtraLine),
path(
'',
SalesOrderExtraLineDetail.as_view(),
name='api-so-extra-line-detail',
),
]),
SalesOrderExtraLineDetail.as_view(),
name='api-so-extra-line-detail',
),
path('', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'),
]),
@@ -2107,7 +2075,6 @@ order_api_urls = [
ReturnOrderReceive.as_view(),
name='api-return-order-receive',
),
meta_path(models.ReturnOrder),
path(
'', ReturnOrderDetail.as_view(), name='api-return-order-detail'
),
@@ -2130,14 +2097,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.ReturnOrderLineItem),
path(
'',
ReturnOrderLineItemDetail.as_view(),
name='api-return-order-line-detail',
),
]),
ReturnOrderLineItemDetail.as_view(),
name='api-return-order-line-detail',
),
# Return order line item status code information
path(
@@ -2157,14 +2118,8 @@ order_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(models.ReturnOrderExtraLine),
path(
'',
ReturnOrderExtraLineDetail.as_view(),
name='api-return-order-extra-line-detail',
),
]),
ReturnOrderExtraLineDetail.as_view(),
name='api-return-order-extra-line-detail',
),
path(
'',

View File

@@ -19,7 +19,6 @@ from InvenTree.api import (
BulkUpdateMixin,
ListCreateDestroyAPIView,
ParameterListMixin,
meta_path,
)
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import (
@@ -1563,14 +1562,8 @@ part_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(PartCategoryParameterTemplate),
path(
'',
CategoryParameterDetail.as_view(),
name='api-part-category-parameter-detail',
),
]),
CategoryParameterDetail.as_view(),
name='api-part-category-parameter-detail',
),
path(
'',
@@ -1581,12 +1574,7 @@ part_api_urls = [
),
# Category detail endpoints
path(
'<int:pk>/',
include([
meta_path(PartCategory),
# PartCategory detail endpoint
path('', CategoryDetail.as_view(), name='api-part-category-detail'),
]),
'<int:pk>/', CategoryDetail.as_view(), name='api-part-category-detail'
),
path('', CategoryList.as_view(), name='api-part-category-list'),
]),
@@ -1597,14 +1585,8 @@ part_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(PartTestTemplate),
path(
'',
PartTestTemplateDetail.as_view(),
name='api-part-test-template-detail',
),
]),
PartTestTemplateDetail.as_view(),
name='api-part-test-template-detail',
),
path(
'', PartTestTemplateList.as_view(), name='api-part-test-template-list'
@@ -1642,13 +1624,7 @@ part_api_urls = [
'related/',
include([
path(
'<int:pk>/',
include([
meta_path(PartRelated),
path(
'', PartRelatedDetail.as_view(), name='api-part-related-detail'
),
]),
'<int:pk>/', PartRelatedDetail.as_view(), name='api-part-related-detail'
),
path('', PartRelatedList.as_view(), name='api-part-related-list'),
]),
@@ -1699,8 +1675,6 @@ part_api_urls = [
path(
'bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'
),
# Part metadata
meta_path(Part),
# Part pricing
path('pricing/', PartPricingDetail.as_view(), name='api-part-pricing'),
# Part detail endpoint
@@ -1717,14 +1691,8 @@ bom_api_urls = [
# Detail view
path(
'<int:pk>/',
include([
meta_path(BomItemSubstitute),
path(
'',
BomItemSubstituteDetail.as_view(),
name='api-bom-substitute-detail',
),
]),
BomItemSubstituteDetail.as_view(),
name='api-bom-substitute-detail',
),
# Catch all
path('', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'),
@@ -1735,7 +1703,6 @@ bom_api_urls = [
'<int:pk>/',
include([
path('validate/', BomItemValidate.as_view(), name='api-bom-item-validate'),
meta_path(BomItem),
path('', BomDetail.as_view(), name='api-bom-item-detail'),
]),
),

View File

@@ -18,7 +18,6 @@ import report.models
import report.serializers
from common.models import DataOutput
from common.serializers import DataOutputSerializer
from InvenTree.api import meta_path
from InvenTree.filters import InvenTreeSearchFilter
from InvenTree.mixins import ListCreateAPI, RetrieveUpdateDestroyAPI
from plugin import PluginMixinEnum
@@ -355,14 +354,8 @@ label_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(report.models.LabelTemplate),
path(
'',
LabelTemplateDetail.as_view(),
name='api-label-template-detail',
),
]),
LabelTemplateDetail.as_view(),
name='api-label-template-detail',
),
path('', LabelTemplateList.as_view(), name='api-label-template-list'),
]),
@@ -378,14 +371,8 @@ report_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(report.models.ReportTemplate),
path(
'',
ReportTemplateDetail.as_view(),
name='api-report-template-detail',
),
]),
ReportTemplateDetail.as_view(),
name='api-report-template-detail',
),
path('', ReportTemplateList.as_view(), name='api-report-template-list'),
]),

View File

@@ -29,12 +29,7 @@ from company.models import Company, ManufacturerPart, SupplierPart
from company.serializers import CompanySerializer
from data_exporter.mixins import DataExportViewMixin
from generic.states.api import StatusView
from InvenTree.api import (
BulkCreateMixin,
BulkUpdateMixin,
ListCreateDestroyAPIView,
meta_path,
)
from InvenTree.api import BulkCreateMixin, BulkUpdateMixin, ListCreateDestroyAPIView
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import (
ORDER_FILTER_ALIAS,
@@ -1666,11 +1661,7 @@ stock_api_urls = [
path('tree/', StockLocationTree.as_view(), name='api-location-tree'),
# Stock location detail endpoints
path(
'<int:pk>/',
include([
meta_path(StockLocation),
path('', StockLocationDetail.as_view(), name='api-location-detail'),
]),
'<int:pk>/', StockLocationDetail.as_view(), name='api-location-detail'
),
path('', StockLocationList.as_view(), name='api-location-list'),
]),
@@ -1681,14 +1672,8 @@ stock_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(StockLocationType),
path(
'',
StockLocationTypeDetail.as_view(),
name='api-location-type-detail',
),
]),
StockLocationTypeDetail.as_view(),
name='api-location-type-detail',
),
path('', StockLocationTypeList.as_view(), name='api-location-type-list'),
]),
@@ -1708,14 +1693,8 @@ stock_api_urls = [
include([
path(
'<int:pk>/',
include([
meta_path(StockItemTestResult),
path(
'',
StockItemTestResultDetail.as_view(),
name='api-stock-test-result-detail',
),
]),
StockItemTestResultDetail.as_view(),
name='api-stock-test-result-detail',
),
path(
'', StockItemTestResultList.as_view(), name='api-stock-test-result-list'
@@ -1747,7 +1726,6 @@ stock_api_urls = [
include([
path('convert/', StockItemConvert.as_view(), name='api-stock-item-convert'),
path('install/', StockItemInstall.as_view(), name='api-stock-item-install'),
meta_path(StockItem),
path(
'serialize/',
StockItemSerialize.as_view(),

View File

@@ -2683,58 +2683,6 @@ class StockMergeTest(StockAPITestCase):
self.assertEqual(StockItem.objects.filter(part=self.part).count(), n - 2)
class StockMetadataAPITest(InvenTreeAPITestCase):
"""Unit tests for the various metadata endpoints of API."""
fixtures = [
'category',
'part',
'test_templates',
'bom',
'company',
'location',
'supplier_part',
'stock',
'stock_tests',
]
roles = ['stock.change', 'stock_location.change']
def metatester(self, raw_url: str, model):
"""Generic tester."""
modeldata = model.objects.first()
# Useless test unless a model object is found
self.assertIsNotNone(modeldata)
url = raw_url.format(pk=modeldata.pk)
# Metadata is initially null
self.assertIsNone(modeldata.metadata)
numstr = f'12{len(raw_url)}'
target_key = f'abc-{numstr}'
target_value = f'xyz-{raw_url}-{numstr}'
# Create / update metadata entry (first try via old addresses)
data = {'metadata': {target_key: target_value}}
rsp = self.patch(url, data, expected_code=301)
self.patch(rsp.url, data, expected_code=200)
# Refresh and check that metadata has been updated
modeldata.refresh_from_db()
self.assertEqual(modeldata.get_metadata(target_key), target_value)
def test_metadata(self):
"""Test all endpoints."""
for raw_url, model in {
'/api/stock/location/{pk}/metadata/': StockLocation,
'/api/stock/test/{pk}/metadata/': StockItemTestResult,
'/api/stock/{pk}/metadata/': StockItem,
}.items():
self.metatester(raw_url, model)
class StockApiPerformanceTest(StockAPITestCase, InvenTreeAPIPerformanceTestCase):
"""Performance tests for the Stock API."""