diff --git a/InvenTree/InvenTree/api.py b/InvenTree/InvenTree/api.py index 81c2ac7f66..19786f59dc 100644 --- a/InvenTree/InvenTree/api.py +++ b/InvenTree/InvenTree/api.py @@ -361,6 +361,10 @@ class MetadataView(RetrieveUpdateAPI): return model + def get_permission_model(self): + """Return the 'permission' model associated with this view""" + return self.get_model_type() + def get_queryset(self): """Return the queryset for this endpoint""" return self.get_model_type().objects.all() diff --git a/InvenTree/InvenTree/metadata.py b/InvenTree/InvenTree/metadata.py index 77398fdf7a..7f3d7bd312 100644 --- a/InvenTree/InvenTree/metadata.py +++ b/InvenTree/InvenTree/metadata.py @@ -7,6 +7,7 @@ from rest_framework.fields import empty from rest_framework.metadata import SimpleMetadata from rest_framework.utils import model_meta +import InvenTree.permissions import users.models from InvenTree.helpers import str2bool @@ -58,7 +59,7 @@ class InvenTreeMetadata(SimpleMetadata): try: # Extract the model name associated with the view - self.model = view.serializer_class.Meta.model + self.model = InvenTree.permissions.get_model_for_view(view) # Construct the 'table name' from the model app_label = self.model._meta.app_label diff --git a/InvenTree/InvenTree/permissions.py b/InvenTree/InvenTree/permissions.py index 4eb087420d..596e924c9e 100644 --- a/InvenTree/InvenTree/permissions.py +++ b/InvenTree/InvenTree/permissions.py @@ -7,6 +7,21 @@ from rest_framework import permissions import users.models +def get_model_for_view(view, raise_error=True): + """Attempt to introspect the 'model' type for an API view""" + + if hasattr(view, 'get_permission_model'): + return view.get_permission_model() + + if hasattr(view, 'serializer_class'): + return view.serializer_class.Meta.model + + if hasattr(view, 'get_serializer_class'): + return view.get_serializr_class().Meta.model + + raise AttributeError(f"Serializer class not specified for {view.__class__}") + + class RolePermission(permissions.BasePermission): """Role mixin for API endpoints, allowing us to specify the user "role" which is required for certain operations. @@ -55,7 +70,7 @@ class RolePermission(permissions.BasePermission): try: # Extract the model name associated with this request - model = view.serializer_class.Meta.model + model = get_model_for_view(view) app_label = model._meta.app_label model_name = model._meta.model_name