fedspendingtransparency/usaspending-api

View on GitHub
usaspending_api/awards/v2/data_layer/orm_utils.py

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
from collections import OrderedDict, MutableMapping
from copy import deepcopy
from django.db.models import F


def delete_keys_from_dict(dictionary):
    """
    Recursive function to remove all keys from a dictionary/OrderedDict which
    start with an underscore: "_"

    parameters:
        - dictionary:  dictionary/OrderedDict

    return:
        OrderedDict
    """
    modified_dict = OrderedDict()
    for key, value in dictionary.items():
        if not key.startswith("_"):
            if isinstance(value, MutableMapping):
                modified_dict[key] = delete_keys_from_dict(value)
            else:
                modified_dict[key] = deepcopy(value)
    return modified_dict


def split_mapper_into_qs(mapper):
    """
    Django ORM has trouble using .annotate() when the destination field conflicts with an
    existing model field, even if it's the same source field (no renaming occurring)

    Assuming there is a dictionary with model field names as keys and the target field as the value,
    Split that into two objects:
        values_list: a list of fields which you wish to retrieve without renaming
            aka when `key` == `value`
        annotate_dict: a dictionary/OrderedDict of target and source fields to rename

    parameters
        - mapper:  dictionary/OrderedDict

    return:
        - values_list: list
        -annotate_dict:  OrderedDict
    """
    values_list = [k for k, v in mapper.items() if k == v]
    annotate_dict = OrderedDict([(v, F(k)) for k, v in mapper.items() if k != v])

    return values_list, annotate_dict