mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-02 19:08:47 +00:00
API / serializer updates
This commit is contained in:
@@ -819,6 +819,47 @@ class AttachmentDetail(AttachmentMixin, RetrieveUpdateDestroyAPI):
|
|||||||
return super().destroy(request, *args, **kwargs)
|
return super().destroy(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class NoteFilter(FilterSet):
|
||||||
|
"""Filterset class for the NoteList API endpoint."""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Metaclass options for the filterset."""
|
||||||
|
|
||||||
|
model = common.models.Note
|
||||||
|
fields = ['model_type', 'model_id', 'updated_by']
|
||||||
|
|
||||||
|
model_type = rest_filters.CharFilter(method='filter_model_type', label='Model Type')
|
||||||
|
|
||||||
|
def filter_model_type(self, queryset, name, value):
|
||||||
|
"""Filter queryset to include only Parameters of the given model type."""
|
||||||
|
return common.filters.filter_content_type(
|
||||||
|
queryset, 'model_type', value, allow_null=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class NoteMixin:
|
||||||
|
"""Mixin class for the Note views."""
|
||||||
|
|
||||||
|
queryset = common.models.Note.objects.all()
|
||||||
|
serializer_class = common.serializers.NoteSerializer
|
||||||
|
permission_classes = [IsAuthenticatedOrReadScope]
|
||||||
|
|
||||||
|
|
||||||
|
class NoteList(NoteMixin, ListCreateAPI):
|
||||||
|
"""List API endpoint for Note objects."""
|
||||||
|
|
||||||
|
filter_backends = SEARCH_ORDER_FILTER
|
||||||
|
filterset_class = NoteFilter
|
||||||
|
|
||||||
|
ordering_fields = ['model_id', 'model_type', 'user', 'creation']
|
||||||
|
search_fields = ['content', 'model_id', 'model_type', 'user__username']
|
||||||
|
unique_create_fields = ['model_type', 'model_id']
|
||||||
|
|
||||||
|
|
||||||
|
class NoteDetail(NoteMixin, RetrieveUpdateDestroyAPI):
|
||||||
|
"""Detail API endpoint for Note objects."""
|
||||||
|
|
||||||
|
|
||||||
class ParameterTemplateFilter(FilterSet):
|
class ParameterTemplateFilter(FilterSet):
|
||||||
"""FilterSet class for the ParameterTemplateList API endpoint."""
|
"""FilterSet class for the ParameterTemplateList API endpoint."""
|
||||||
|
|
||||||
@@ -1477,6 +1518,20 @@ common_api_urls = [
|
|||||||
path('', AttachmentList.as_view(), name='api-attachment-list'),
|
path('', AttachmentList.as_view(), name='api-attachment-list'),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
# Notes
|
||||||
|
path(
|
||||||
|
'note/',
|
||||||
|
include([
|
||||||
|
path(
|
||||||
|
'<int:pk>/',
|
||||||
|
include([
|
||||||
|
meta_path(common.models.Note),
|
||||||
|
path('', NoteDetail.as_view(), name='api-note-detail'),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
path('', NoteList.as_view(), name='api-note-list'),
|
||||||
|
]),
|
||||||
|
),
|
||||||
# Parameters and templates
|
# Parameters and templates
|
||||||
path(
|
path(
|
||||||
'parameter/',
|
'parameter/',
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.2.14 on 2026-05-18 13:55
|
# Generated by Django 5.2.14 on 2026-05-18 14:16
|
||||||
|
|
||||||
import InvenTree.models
|
import InvenTree.models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
@@ -62,6 +62,12 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="Description",
|
verbose_name="Description",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"content",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, help_text="Note content", verbose_name="Content"
|
||||||
|
),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"model_type",
|
"model_type",
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
|
|||||||
@@ -2987,6 +2987,10 @@ class Note(
|
|||||||
help_text=_('Optional description field'),
|
help_text=_('Optional description field'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
content = models.TextField(
|
||||||
|
blank=True, verbose_name=_('Content'), help_text=_('Note content')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BarcodeScanResult(InvenTree.models.InvenTreeModel):
|
class BarcodeScanResult(InvenTree.models.InvenTreeModel):
|
||||||
"""Model for storing barcode scans results."""
|
"""Model for storing barcode scans results."""
|
||||||
|
|||||||
@@ -809,6 +809,82 @@ class AttachmentSerializer(FilterableSerializerMixin, InvenTreeModelSerializer):
|
|||||||
return super().save(**kwargs)
|
return super().save(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class NoteSerializer(InvenTreeModelSerializer):
|
||||||
|
"""Serializer for the Note model."""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta options for NoteSerializer."""
|
||||||
|
|
||||||
|
model = common_models.Note
|
||||||
|
fields = [
|
||||||
|
'pk',
|
||||||
|
'model_type',
|
||||||
|
'model_id',
|
||||||
|
'title',
|
||||||
|
'description',
|
||||||
|
'content',
|
||||||
|
'updated',
|
||||||
|
'updated_by',
|
||||||
|
]
|
||||||
|
|
||||||
|
read_only_fields = ['updated', 'updated_by']
|
||||||
|
|
||||||
|
def save(self, **kwargs):
|
||||||
|
"""Save the Note instance."""
|
||||||
|
from InvenTree.models import InvenTreeNoteMixin
|
||||||
|
from users.permissions import check_user_permission
|
||||||
|
|
||||||
|
model_type = self.validated_data.get('model_type', None)
|
||||||
|
|
||||||
|
if model_type is None and self.instance:
|
||||||
|
model_type = self.instance.model_type
|
||||||
|
|
||||||
|
# Ensure that the user has permission to modify notes for the specified model
|
||||||
|
user = self.context.get('request').user
|
||||||
|
|
||||||
|
target_model_class = model_type.model_class()
|
||||||
|
|
||||||
|
if not issubclass(target_model_class, InvenTreeNoteMixin):
|
||||||
|
raise PermissionDenied(_('Invalid model type specified for note'))
|
||||||
|
|
||||||
|
permission_error_msg = _(
|
||||||
|
'User does not have permission to create or edit notes for this model'
|
||||||
|
)
|
||||||
|
|
||||||
|
if not check_user_permission(user, target_model_class, 'change'):
|
||||||
|
raise PermissionDenied(permission_error_msg)
|
||||||
|
|
||||||
|
if not target_model_class.check_related_permission('change', user):
|
||||||
|
raise PermissionDenied(permission_error_msg)
|
||||||
|
|
||||||
|
instance = super().save(**kwargs)
|
||||||
|
instance.updated_by = user
|
||||||
|
instance.save()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
# Note: The choices are overridden at run-time on class initialization
|
||||||
|
model_type = ContentTypeField(
|
||||||
|
mixin_class=InvenTreeParameterMixin,
|
||||||
|
choices=common.validators.note_model_options,
|
||||||
|
label=_('Model Type'),
|
||||||
|
default='',
|
||||||
|
allow_null=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
updated_by_detail = OptionalField(
|
||||||
|
serializer_class=UserSerializer,
|
||||||
|
serializer_kwargs={
|
||||||
|
'source': 'updated_by',
|
||||||
|
'read_only': True,
|
||||||
|
'allow_null': True,
|
||||||
|
'many': False,
|
||||||
|
},
|
||||||
|
default_include=True,
|
||||||
|
prefetch_fields=['updated_by'],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@register_importer()
|
@register_importer()
|
||||||
class ParameterTemplateSerializer(
|
class ParameterTemplateSerializer(
|
||||||
DataImportExportSerializerMixin, InvenTreeModelSerializer
|
DataImportExportSerializerMixin, InvenTreeModelSerializer
|
||||||
|
|||||||
@@ -9,6 +9,23 @@ import common.icons
|
|||||||
from common.settings import get_global_setting
|
from common.settings import get_global_setting
|
||||||
|
|
||||||
|
|
||||||
|
def note_model_types():
|
||||||
|
"""Return a list of valid note model choices."""
|
||||||
|
import InvenTree.models
|
||||||
|
|
||||||
|
return list(
|
||||||
|
InvenTree.helpers_model.getModelsWithMixin(InvenTree.models.InvenTreeNotesMixin)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def note_model_options():
|
||||||
|
"""Return a list of options for models which support notes."""
|
||||||
|
return [
|
||||||
|
(model.__name__.lower(), model._meta.verbose_name)
|
||||||
|
for model in note_model_types()
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def parameter_model_types():
|
def parameter_model_types():
|
||||||
"""Return a list of valid parameter model choices."""
|
"""Return a list of valid parameter model choices."""
|
||||||
import InvenTree.models
|
import InvenTree.models
|
||||||
|
|||||||
Reference in New Issue
Block a user