2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-16 17:28:11 +00:00

Update InvenTreeParameterMixin class

- Fetch queryset of all linked Parameter instances
- Ensure deletion of linked instances
This commit is contained in:
Oliver Walters
2025-11-10 11:19:40 +00:00
parent c349152d30
commit c1cd327fc2
3 changed files with 47 additions and 24 deletions

View File

@@ -466,15 +466,56 @@ class InvenTreeMetadataModel(MetadataMixin, InvenTreeModel):
abstract = True abstract = True
class InvenTreeParameterMixin: class InvenTreePermissionCheckMixin:
"""Provides an abstracted class for managing permissions against related fields."""
@classmethod
def check_related_permission(cls, permission, user) -> bool:
"""Check if the user has permission to perform the specified action on the attachment.
The default implementation runs a permission check against *this* model class,
but this can be overridden in the implementing class if required.
Arguments:
permission: The permission to check (add / change / view / delete)
user: The user to check against
Returns:
bool: True if the user has permission, False otherwise
"""
perm = f'{cls._meta.app_label}.{permission}_{cls._meta.model_name}'
return user.has_perm(perm)
class InvenTreeParameterMixin(InvenTreePermissionCheckMixin):
"""Provides an abstracted class for managing parameters. """Provides an abstracted class for managing parameters.
Links the implementing model to the common.models.Parameter table, Links the implementing model to the common.models.Parameter table,
and provides the following methods: and provides the following methods:
""" """
def delete(self, *args, **kwargs):
"""Handle the deletion of a model instance.
class InvenTreeAttachmentMixin: Before deleting the model instance, delete any associated parameters.
"""
self.parameters.all().delete()
super().delete(*args, **kwargs)
@property
def parameters(self) -> QuerySet:
"""Return a queryset containing all parameters for this model."""
return self.parameters_for_model().filter(model_id=self.pk)
def parameters_for_model(self) -> QuerySet:
"""Return a QuerySet containing all parameters for this model class."""
from common.models import Parameter
model_type = self.__class__.__name__.lower()
return Parameter.objects.filter(model_type=model_type)
class InvenTreeAttachmentMixin(InvenTreePermissionCheckMixin):
"""Provides an abstracted class for managing file attachments. """Provides an abstracted class for managing file attachments.
Links the implementing model to the common.models.Attachment table, Links the implementing model to the common.models.Attachment table,
@@ -492,33 +533,15 @@ class InvenTreeAttachmentMixin:
super().delete(*args, **kwargs) super().delete(*args, **kwargs)
@property @property
def attachments(self): def attachments(self) -> QuerySet:
"""Return a queryset containing all attachments for this model.""" """Return a queryset containing all attachments for this model."""
return self.attachments_for_model().filter(model_id=self.pk) return self.attachments_for_model().filter(model_id=self.pk)
@classmethod def attachments_for_model(self) -> QuerySet:
def check_attachment_permission(cls, permission, user) -> bool:
"""Check if the user has permission to perform the specified action on the attachment.
The default implementation runs a permission check against *this* model class,
but this can be overridden in the implementing class if required.
Arguments:
permission: The permission to check (add / change / view / delete)
user: The user to check against
Returns:
bool: True if the user has permission, False otherwise
"""
perm = f'{cls._meta.app_label}.{permission}_{cls._meta.model_name}'
return user.has_perm(perm)
def attachments_for_model(self):
"""Return all attachments for this model class.""" """Return all attachments for this model class."""
from common.models import Attachment from common.models import Attachment
model_type = self.__class__.__name__.lower() model_type = self.__class__.__name__.lower()
return Attachment.objects.filter(model_type=model_type) return Attachment.objects.filter(model_type=model_type)
def create_attachment(self, attachment=None, link=None, comment='', **kwargs): def create_attachment(self, attachment=None, link=None, comment='', **kwargs):

View File

@@ -2061,7 +2061,7 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel
if not issubclass(model_class, InvenTreeAttachmentMixin): if not issubclass(model_class, InvenTreeAttachmentMixin):
raise ValidationError(_('Invalid model type specified for attachment')) raise ValidationError(_('Invalid model type specified for attachment'))
return model_class.check_attachment_permission(permission, user) return model_class.check_related_permission(permission, user)
class InvenTreeCustomUserStateModel(models.Model): class InvenTreeCustomUserStateModel(models.Model):

View File

@@ -691,7 +691,7 @@ class AttachmentSerializer(InvenTreeModelSerializer):
raise PermissionDenied(permission_error_msg) raise PermissionDenied(permission_error_msg)
# Check that the user has the required permissions to attach files to the target model # Check that the user has the required permissions to attach files to the target model
if not target_model_class.check_attachment_permission('change', user): if not target_model_class.check_related_permission('change', user):
raise PermissionDenied(_(permission_error_msg)) raise PermissionDenied(_(permission_error_msg))
return super().save(**kwargs) return super().save(**kwargs)