dabapps / django-rest-framework-serialization-spec

DEPRECATED, see https://github.com/dabapps/django-readers instead
MIT License
11 stars 0 forks source link

Merge different prefetches of same keys #19

Closed pmg103 closed 5 years ago

pmg103 commented 5 years ago

If you ask for

  serialization_spec = [
    {'organisation': [
      'id',
    ]),
    {'organisation': [
      'name',
    ]),
  ]

Then as it stands this will not work. If the duplication occurred further down the tree, then it would work, but multiple different prefetches would be generated which is suboptimal.

A nice solution to both issues would be to ensure the serialization_spec was in fully normal form -- ie a single tree with no duplicates. Any duplicate subtrees would be merged. Thus the above would result in an output as if it had been:

  serialization_spec = [
    {'organisation': [
      'id',
      'name'
    ]),
  ]
pmg103 commented 5 years ago

something like this

def _normalise_spec(spec, existing_fields, existing_relations):
  normalized_fields = deepcopy(existing_fields)
  normalized_relations = deepcopy(existing_relations)
  for each in spec:
    if isinstance(each, dict):
      for key, childspec in each.items():
         child_fields, child_relations = normalized_relations.get(key, [set(), {}])
         normalized_relations[key] = _normalise_spec(childspec, child_fields, child_relations)
    else:
      if each not in normalized_fields:
        normalized_fields.add(each)
  return normalized_fields, normalized_relations

def normalise_spec(spec):
  normalized_fields, normalized_relations = _normalise_spec(spec, set(), {})
  return list(normalized_fields) + [normalized_relations]