I am trying to write a orm package which source data is json, First I created a Department class (I am trying to mimic django model)
class Department(): def __init__(self, data_dict): self.id = data_dict['id'] self.organization_name = data_dict['organization_name'] def __str__(self): return f"<{self.__class__.__name__}(id={self.id})>"
Then I created Organization class as a search manager.
class Organization(): data = [{ "id": 1, "parent_id": 0, "organization_name": "President Office" },{ "id": 2, "parent_id": 1, "organization_name": "Business Development Dept." },{ "id": 3, "parent_id": 2, "organization_name": "Product Design Dept." }] def get(self,id): department_instance = None for department_dict in self.data: if department_dict['id'] == id: department_instance = Department(department_dict) break return department_instance
My expected result is:
org = Organization() business_dev_dep = org.get(id=2) # <Department(id=2)> business_dev_dep.parent_id # <Department(id=1)>
But I have no idea how to achieve it, can anybody help me?
Advertisement
Answer
If you want to access the parent object instance by class attribute you have to declare it in the Department class:
class Department(object): def __init__(self, data_dict): self.id = data_dict['id'] self.parent_id = None self.organization_name = data_dict['organization_name'] def __str__(self): return f"<{self.__class__.__name__}(id={self.id})>"
Then in your Organization
class you can write a new method that searchs for the parent data and sets the attribute before returning it:
class Organization(object): data = [{ "id": 1, "parent_id": 0, "organization_name": "President Office" }, { "id": 2, "parent_id": 1, "organization_name": "Business Development Dept." }, { "id": 3, "parent_id": 2, "organization_name": "Product Design Dept." }] def _get_parent(self, parent_id): # id == 0 means that the object doesn't have parent? if parent_id > 0 and parent_id in map(lambda x: x['parent_id'], self.data): parent_data = list(filter(lambda x: x['id'] == parent_id, self.data)).pop() return Department(parent_data) def get(self, id): department_instance = None for department_dict in self.data: if department_dict['id'] == id: department_instance = Department(department_dict) department_instance.parent_id = self._get_parent(department_dict['parent_id']) break return department_instance
Then you can access the parent attribute like you’re expecting:
org = Organization() business_dev_dep = org.get(id=2) # <Department(id=2)> business_dev_dep.parent_id
EDIT: That snippet only gets the first parent in the hierarchy. If you want to get all children from any node then you must rewrite the _get_parent
function to be recursive:
class Organization(object): data = [{ "id": 1, "parent_id": 0, "organization_name": "President Office" }, { "id": 2, "parent_id": 1, "organization_name": "Business Development Dept." }, { "id": 3, "parent_id": 2, "organization_name": "Product Design Dept." }] def _get_parent(self, parent_id): # id == 0 means that the object doesn't have parent? if parent_id > 0 and parent_id in map(lambda x: x['parent_id'], self.data): parent_data = list(filter(lambda x: x['id'] == parent_id, self.data)).pop() parent = Department(parent_data) parent.parent_id = self._get_parent(parent_data['parent_id']) return parent def get(self, id): department_instance = None for department_dict in self.data: if department_dict['id'] == id: department_instance = Department(department_dict) department_instance.parent_id = self._get_parent(department_dict['parent_id']) break return department_instance
Now you can access all the parent objects from any node:
org = Organization() business_dev_dep = org.get(id=3) print(business_dev_dep.parent_id.parent_id) <Department(id=1)>