@@ -448,6 +448,8 @@ class ObjectTagView(
448448
449449 # Serializer used in `get_queryset` when getting tags per taxonomy
450450 serializer_class = ObjectTagSerializer
451+ # Serializer used in `retrieve` to represent all tags of a given object
452+ object_tags_serializer_class = ObjectTagsByTaxonomySerializer
451453 # Serializer used in the result in `to_representation` in `ObjectTagsByTaxonomySerializer`
452454 minimal_serializer_class = ObjectTagMinimalSerializer
453455 permission_classes = [ObjectTagObjectPermissions ]
@@ -471,23 +473,29 @@ def get_queryset(self) -> models.QuerySet:
471473 taxonomy = taxonomy .cast ()
472474 taxonomy_id = taxonomy .id
473475
474- if object_id .endswith ("*" ) or "," in object_id : # pylint: disable=no-else-raise
475- raise ValidationError ("Retrieving tags from multiple objects is not yet supported." )
476+ if object_id .endswith ("*" ) or "," in object_id :
476477 # Note: This API is actually designed so that in the future it can be extended to return tags for multiple
477478 # objects, e.g. if object_id.endswith("*") then it results in a object_id__startswith query. However, for
478479 # now we have no use case for that so we retrieve tags for one object at a time.
479- else :
480- if not self .request .user .has_perm (
481- "oel_tagging.view_objecttag" ,
482- # The obj arg expects a model, but we are passing an object
483- ObjectTagPermissionItem (taxonomy = taxonomy , object_id = object_id ), # type: ignore[arg-type]
484- ):
485- raise PermissionDenied (
486- "You do not have permission to view object tags for this taxonomy or object_id."
487- )
480+ raise ValidationError ("Retrieving tags from multiple objects is not yet supported." )
481+
482+ self .ensure_has_view_object_tag_permission (self .request .user , taxonomy , object_id )
488483
489484 return get_object_tags (object_id , taxonomy_id )
490485
486+ def ensure_has_view_object_tag_permission (self , user , taxonomy , object_id ):
487+ """
488+ Check if user has permission to view object tags.
489+ """
490+ if not user .has_perm (
491+ "oel_tagging.view_objecttag" ,
492+ # The obj arg expects a model, but we are passing an object
493+ ObjectTagPermissionItem (taxonomy = taxonomy , object_id = object_id ), # type: ignore[arg-type]
494+ ):
495+ raise PermissionDenied (
496+ "You do not have permission to view object tags for this taxonomy or object_id."
497+ )
498+
491499 def retrieve (self , request , * args , ** kwargs ) -> Response :
492500 """
493501 Retrieve ObjectTags that belong to a given object_id
@@ -500,7 +508,7 @@ def retrieve(self, request, *args, **kwargs) -> Response:
500508 behavior we want.
501509 """
502510 object_tags = self .filter_queryset (self .get_queryset ())
503- serializer = ObjectTagsByTaxonomySerializer (list (object_tags ), context = self .get_serializer_context ())
511+ serializer = self . object_tags_serializer_class (list (object_tags ), context = self .get_serializer_context ())
504512 response_data = serializer .data
505513 if self .kwargs ["object_id" ] not in response_data :
506514 # For consistency, the key with the object_id should always be present in the response, even if there
@@ -514,7 +522,7 @@ def update(self, request, *args, **kwargs) -> Response:
514522
515523 Pass a list of Tag ids or Tag values to be applied to an object id in the
516524 body `tag` parameter, by each taxonomy. Passing an empty list will remove all tags from
517- the object id on an specific taxonomy.
525+ the object id on a specific taxonomy.
518526
519527 **Example Body Requests**
520528
@@ -550,13 +558,13 @@ def update(self, request, *args, **kwargs) -> Response:
550558 },
551559 ]
552560 }
561+ ```
553562 """
554563 partial = kwargs .pop ('partial' , False )
555564 if partial :
556565 raise MethodNotAllowed ("PATCH" , detail = "PATCH not allowed" )
557566
558567 object_id = kwargs .pop ('object_id' )
559- perm = "oel_tagging.can_tag_object"
560568 body = ObjectTagUpdateBodySerializer (data = request .data )
561569 body .is_valid (raise_exception = True )
562570
@@ -566,14 +574,33 @@ def update(self, request, *args, **kwargs) -> Response:
566574 return self .retrieve (request , object_id )
567575
568576 # Check permissions
569- for tagsData in data :
570- taxonomy = tagsData .get ("taxonomy" )
577+ self .ensure_user_has_can_tag_object_permissions (request .user , data , object_id )
578+
579+ # Tag object_id per taxonomy
580+ for tag_data in data :
581+ taxonomy = tag_data .get ("taxonomy" )
582+ tags = tag_data .get ("tags" , [])
583+ try :
584+ tag_object (object_id , taxonomy , tags )
585+ except TagDoesNotExist as e :
586+ raise ValidationError from e
587+ except ValueError as e :
588+ raise ValidationError from e
571589
590+ return self .retrieve (request , object_id )
591+
592+ def ensure_user_has_can_tag_object_permissions (self , user , tags_data , object_id ):
593+ """
594+ Check if user has permission to tag object for each taxonomy.
595+ """
596+ perm = "oel_tagging.can_tag_object"
597+ for tag_data in tags_data :
598+ taxonomy = tag_data .get ("taxonomy" )
572599 perm_obj = ObjectTagPermissionItem (
573600 taxonomy = taxonomy ,
574601 object_id = object_id ,
575602 )
576- if not request . user .has_perm (
603+ if not user .has_perm (
577604 perm ,
578605 # The obj arg expects a model, but we are passing an object
579606 perm_obj , # type: ignore[arg-type]
@@ -583,19 +610,6 @@ def update(self, request, *args, **kwargs) -> Response:
583610 for Taxonomy: { str (taxonomy )} or Object: { object_id } .
584611 """ )
585612
586- # Tag object_id per taxonomy
587- for tagsData in data :
588- taxonomy = tagsData .get ("taxonomy" )
589- tags = tagsData .get ("tags" , [])
590- try :
591- tag_object (object_id , taxonomy , tags )
592- except TagDoesNotExist as e :
593- raise ValidationError from e
594- except ValueError as e :
595- raise ValidationError from e
596-
597- return self .retrieve (request , object_id )
598-
599613
600614@view_auth_classes
601615class ObjectTagCountsView (
0 commit comments