2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-27 19:16:44 +00:00

refactor(backend): metadata endpoint (#9488)

* refactor(backend): simplify metadata endpoint

* fix imports

* simplify even more

* remove unneeded schema tooling

* fix attr handling
This commit is contained in:
Matthias Mair 2025-04-10 01:09:52 +02:00 committed by GitHub
parent 4ea8f68819
commit dc1acfdacb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 54 additions and 93 deletions

View File

@ -1,7 +1,6 @@
"""Main JSON interface views."""
import json
import sys
from pathlib import Path
from django.conf import settings
@ -18,15 +17,14 @@ from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from rest_framework.views import APIView
import common.models
import InvenTree.ready
import InvenTree.version
import users.models
from common.settings import get_global_setting
from InvenTree import helpers, ready
from InvenTree import helpers
from InvenTree.auth_overrides import registration_enabled
from InvenTree.mixins import ListCreateAPI
from InvenTree.sso import sso_registration_enabled
from part.models import Part
from plugin.serializers import MetadataSerializer
from users.models import ApiToken
@ -707,37 +705,32 @@ class APISearchView(GenericAPIView):
class MetadataView(RetrieveUpdateAPI):
"""Generic API endpoint for reading and editing metadata for a model."""
MODEL_REF = 'model'
def get_model_type(self):
"""Return the model type associated with this API instance."""
model = self.kwargs.get(self.MODEL_REF, None)
if ready.isGeneratingSchema():
model = common.models.ProjectCode
if 'lookup_field' in self.kwargs:
# Set custom lookup field (instead of default 'pk' value) if supplied
self.lookup_field = self.kwargs.pop('lookup_field')
model = None # Placeholder for the model class
@classmethod
def as_view(cls, model, lookup_field=None, **initkwargs):
"""Override to ensure model specific rendering."""
if model is None:
raise ValidationError(
f"MetadataView called without '{self.MODEL_REF}' parameter"
"MetadataView defined without 'model' arg"
) # pragma: no cover
initkwargs['model'] = model
return model
# Set custom lookup field (instead of default 'pk' value) if supplied
if lookup_field:
initkwargs['lookup_field'] = lookup_field
return super().as_view(**initkwargs)
def get_permission_model(self):
"""Return the 'permission' model associated with this view."""
return self.get_model_type()
return self.model
def get_queryset(self):
"""Return the queryset for this endpoint."""
return self.get_model_type().objects.all()
return self.model.objects.all()
def get_serializer(self, *args, **kwargs):
"""Return MetadataSerializer instance."""
# Detect if we are currently generating the OpenAPI schema
if 'spectacular' in sys.argv:
return MetadataSerializer(Part, *args, **kwargs) # pragma: no cover
return MetadataSerializer(self.get_model_type(), *args, **kwargs)
return MetadataSerializer(self.model, *args, **kwargs)

View File

@ -920,8 +920,7 @@ build_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': BuildItem},
MetadataView.as_view(model=BuildItem),
name='api-build-item-metadata',
),
path('', BuildItemDetail.as_view(), name='api-build-item-detail'),
@ -967,8 +966,7 @@ build_api_urls = [
path('unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
path(
'metadata/',
MetadataView.as_view(),
{'model': Build},
MetadataView.as_view(model=Build),
name='api-build-metadata',
),
path('', BuildDetail.as_view(), name='api-build-detail'),

View File

@ -986,8 +986,7 @@ common_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': common.models.Attachment},
MetadataView.as_view(model=common.models.Attachment),
name='api-attachment-metadata',
),
path('', AttachmentDetail.as_view(), name='api-attachment-detail'),
@ -1012,8 +1011,7 @@ common_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': common.models.ProjectCode},
MetadataView.as_view(model=common.models.ProjectCode),
name='api-project-code-metadata',
),
path(

View File

@ -516,8 +516,7 @@ manufacturer_part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': ManufacturerPart},
MetadataView.as_view(model=ManufacturerPart),
name='api-manufacturer-part-metadata',
),
path(
@ -538,8 +537,7 @@ supplier_part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': SupplierPart},
MetadataView.as_view(model=SupplierPart),
name='api-supplier-part-metadata',
),
path('', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
@ -574,8 +572,7 @@ company_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': Company},
MetadataView.as_view(model=Company),
name='api-company-metadata',
),
path('', CompanyDetail.as_view(), name='api-company-detail'),
@ -589,8 +586,7 @@ company_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': Contact},
MetadataView.as_view(model=Contact),
name='api-contact-metadata',
),
path('', ContactDetail.as_view(), name='api-contact-detail'),

View File

@ -1779,8 +1779,7 @@ order_api_urls = [
path('issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'),
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrder},
MetadataView.as_view(model=models.PurchaseOrder),
name='api-po-metadata',
),
path(
@ -1812,8 +1811,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrderLineItem},
MetadataView.as_view(model=models.PurchaseOrderLineItem),
name='api-po-line-metadata',
),
path(
@ -1835,8 +1833,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.PurchaseOrderExtraLine},
MetadataView.as_view(model=models.PurchaseOrderExtraLine),
name='api-po-extra-line-metadata',
),
path(
@ -1868,8 +1865,7 @@ order_api_urls = [
),
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderShipment},
MetadataView.as_view(model=models.SalesOrderShipment),
name='api-so-shipment-metadata',
),
path(
@ -1910,8 +1906,7 @@ order_api_urls = [
),
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrder},
MetadataView.as_view(model=models.SalesOrder),
name='api-so-metadata',
),
# SalesOrder detail endpoint
@ -1938,8 +1933,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderLineItem},
MetadataView.as_view(model=models.SalesOrderLineItem),
name='api-so-line-metadata',
),
path(
@ -1961,8 +1955,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.SalesOrderExtraLine},
MetadataView.as_view(model=models.SalesOrderExtraLine),
name='api-so-extra-line-metadata',
),
path(
@ -2018,8 +2011,7 @@ order_api_urls = [
),
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrder},
MetadataView.as_view(model=models.ReturnOrder),
name='api-return-order-metadata',
),
path(
@ -2047,8 +2039,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrderLineItem},
MetadataView.as_view(model=models.ReturnOrderLineItem),
name='api-return-order-line-metadata',
),
path(
@ -2079,8 +2070,7 @@ order_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': models.ReturnOrderExtraLine},
MetadataView.as_view(model=models.ReturnOrderExtraLine),
name='api-return-order-extra-line-metadata',
),
path(

View File

@ -1996,8 +1996,9 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartCategoryParameterTemplate},
MetadataView.as_view(
model=PartCategoryParameterTemplate
),
name='api-part-category-parameter-metadata',
),
path(
@ -2020,8 +2021,7 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartCategory},
MetadataView.as_view(model=PartCategory),
name='api-part-category-metadata',
),
# PartCategory detail endpoint
@ -2040,8 +2040,7 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartTestTemplate},
MetadataView.as_view(model=PartTestTemplate),
name='api-part-test-template-metadata',
),
path(
@ -2091,8 +2090,7 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartRelated},
MetadataView.as_view(model=PartRelated),
name='api-part-related-metadata',
),
path(
@ -2115,8 +2113,7 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartParameterTemplate},
MetadataView.as_view(model=PartParameterTemplate),
name='api-part-parameter-template-metadata',
),
path(
@ -2138,8 +2135,7 @@ part_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': PartParameter},
MetadataView.as_view(model=PartParameter),
name='api-part-parameter-metadata',
),
path(
@ -2217,10 +2213,7 @@ part_api_urls = [
),
# Part metadata
path(
'metadata/',
MetadataView.as_view(),
{'model': Part},
name='api-part-metadata',
'metadata/', MetadataView.as_view(model=Part), name='api-part-metadata'
),
# Part pricing
path('pricing/', PartPricingDetail.as_view(), name='api-part-pricing'),
@ -2241,8 +2234,7 @@ bom_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': BomItemSubstitute},
MetadataView.as_view(model=BomItemSubstitute),
name='api-bom-substitute-metadata',
),
path(
@ -2263,8 +2255,7 @@ bom_api_urls = [
path('validate/', BomItemValidate.as_view(), name='api-bom-item-validate'),
path(
'metadata/',
MetadataView.as_view(),
{'model': BomItem},
MetadataView.as_view(model=BomItem),
name='api-bom-item-metadata',
),
path('', BomDetail.as_view(), name='api-bom-item-detail'),

View File

@ -502,8 +502,9 @@ plugin_api_urls = [
),
path(
'metadata/',
PluginMetadataView.as_view(),
{'model': PluginConfig, 'lookup_field': 'key'},
PluginMetadataView.as_view(
model=PluginConfig, lookup_field='key'
),
name='api-plugin-metadata',
),
path(

View File

@ -362,8 +362,7 @@ label_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': report.models.LabelTemplate},
MetadataView.as_view(model=report.models.LabelTemplate),
name='api-label-template-metadata',
),
path(
@ -390,8 +389,7 @@ report_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': report.models.ReportTemplate},
MetadataView.as_view(model=report.models.ReportTemplate),
name='api-report-template-metadata',
),
path(

View File

@ -1511,8 +1511,7 @@ stock_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': StockLocation},
MetadataView.as_view(model=StockLocation),
name='api-location-metadata',
),
path('', StockLocationDetail.as_view(), name='api-location-detail'),
@ -1530,8 +1529,7 @@ stock_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': StockLocationType},
MetadataView.as_view(model=StockLocationType),
name='api-location-type-metadata',
),
path(
@ -1561,8 +1559,7 @@ stock_api_urls = [
include([
path(
'metadata/',
MetadataView.as_view(),
{'model': StockItemTestResult},
MetadataView.as_view(model=StockItemTestResult),
name='api-stock-test-result-metadata',
),
path(
@ -1604,8 +1601,7 @@ stock_api_urls = [
path('install/', StockItemInstall.as_view(), name='api-stock-item-install'),
path(
'metadata/',
MetadataView.as_view(),
{'model': StockItem},
MetadataView.as_view(model=StockItem),
name='api-stock-item-metadata',
),
path('return/', StockItemReturn.as_view(), name='api-stock-item-return'),