Skip to content

Commit 86ac48d

Browse files
author
Colton Provias
committed
delete_relationships now allows custom descriptors
1 parent 0ac4144 commit 86ac48d

1 file changed

Lines changed: 48 additions & 7 deletions

File tree

sqlalchemy_jsonapi/serializer.py

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)