@@ -440,10 +440,12 @@ def _check_instance_relationships_for_delete(self, instance):
440440
441441 :param instance: The instance to check the relationships of.
442442 """
443- check_permission (instance , None , Permissions .DELTE )
443+ check_permission (instance , None , Permissions .DELETE )
444444 for rel_key , rel in instance .__mapper__ .relationships .items ():
445445 check_permission (instance , rel_key , Permissions .EDIT )
446+
446447 if rel .cascade .delete :
448+
447449 if rel .direction == MANYTOONE :
448450 related = getattr (instance , rel_key )
449451 self ._check_instance_relationships_for_delete (related )
@@ -462,9 +464,12 @@ def _parse_fields(self, query):
462464 k : v
463465 for k , v in query .items () if k .startswith ('fields[' )
464466 }
467+
465468 fields = {}
469+
466470 for k , v in field_args .items ():
467471 fields [k [7 :- 1 ]] = v
472+
468473 return fields
469474
470475 def _parse_include (self , include ):
@@ -480,9 +485,11 @@ def _parse_include(self, include):
480485 else :
481486 local = item
482487 remote = None
488+
483489 ret .setdefault (local , [])
484490 if remote :
485491 ret [local ].append (remote )
492+
486493 return ret
487494
488495 def _parse_page (self , query ):
@@ -492,49 +499,83 @@ def _parse_page(self, query):
492499 :param query: Dict of query args
493500 """
494501 args = {k [5 :- 1 ]: v for k , v in query .items () if k .startswith ('page[' )}
502+
495503 if {'number' , 'size' } == set (args .keys ()):
496504 if not args ['number' ].isdecimal () or not args ['size' ].isdecimal ():
497505 raise BadRequestError ('Page query parameters must be integers' )
506+
498507 number = int (args ['number' ])
499508 size = int (args ['size' ])
500509 start = number * size
510+
501511 return start , start + size - 1
512+
502513 if {'limit' , 'offset' } == set (args .keys ()):
503514 if not args ['limit' ].isdecimal () or not args ['offset' ].isdecimal ():
504515 raise BadRequestError ('Page query parameters must be integers' )
516+
505517 limit = int (args ['limit' ])
506518 offset = int (args ['offset' ])
519+
507520 return offset , offset + limit - 1
521+
508522 return 0 , None
509523
510524 @inject_model
511525 @inject_resource (Permissions .EDIT )
512526 @inject_relationship (Permissions .DELETE )
513- def delete_relationship (self , session , data , model , resource , relationship
514- ):
527+ def delete_relationship (self , session , data , model , resource ,
528+ relationship ):
529+ """
530+ Delete a resource or multiple resources from a to-many relationship.
531+
532+ :param session: SQLAlchemy session
533+ :param data: JSON data provided with the request
534+ :param api_type: The resource type
535+ :param obj_id: Resource ID
536+ :param relationship: Relationship name
537+ """
515538 self ._check_json_data (data )
539+
516540 if relationship .direction == MANYTOONE :
517541 return ToManyExpectedError (model , resource , relationship )
542+
518543 response = JSONAPIResponse ()
519544 response .data = {'data' : []}
545+
520546 session .add (resource )
521- rel = getattr (resource , relationship .key )
547+
548+ remove = get_rel_desc (resource ,
549+ relationship .key ,
550+ RelationshipActions .DELETE )
522551 reverse_side = relationship .back_populates
552+
523553 for item in data ['data' ]:
524- item = self ._fetch_resource (session , item ['type' ], item ['id' ],
554+ item = self ._fetch_resource (session ,
555+ item ['type' ],
556+ item ['id' ],
525557 Permissions .EDIT )
558+
526559 if reverse_side :
527560 reverse_rel = getattr (item , reverse_side )
561+
528562 if reverse_rel .direction == MANYTOONE :
529563 permission = Permissions .EDIT
530564 else :
531565 permission = Permissions .DELETE
566+
532567 check_permission (item , reverse_side , permission )
533- rel .remove (item )
568+
569+ remove (resource , item )
570+
534571 session .commit ()
535572 session .refresh (resource )
536- for item in getattr (resource , relationship .key ):
573+
574+ get = get_rel_desc (resource , relationship .key , RelationshipActions .GET )
575+
576+ for item in get (resource ):
537577 response .data ['data' ].append (self ._render_short_instance (item ))
578+
538579 return response
539580
540581 @inject_model
0 commit comments