Реализовать рекурсивную функцию для проверки наличия или отсутствия дочерних моделей
Я пытаюсь реализовать рекурсивную функцию, которая будет проверять, есть ли у объекта ребенок с идентификатором родителя. Если имеет, то добавляет его в список и рекурсивно вызывает функцию, чтобы проверить, есть ли у вновь добавленного ребенка другие дети.
Мой текущий код, который работает нормально, как и ожидалось:
def get_nav_items(self, instance):
childs = []
items = Content.objects.filter(parent_id=instance)
for item in items:
childs.append(item)
for item in items:
ch = Content.objects.filter(parent_id=item)
if ch.count() > 0:
for c in ch:
childs.append(c)
menu_objecs = []
for item in childs:
menu_objecs.append(ContentNevItemSerializer(item).data)
return menu_objecs
Метод, который сейчас не возвращает никакого результата:
def extract_item(self, nav_obj, nav_list = []):
cont = Content.objects.filter(parent_id=nav_obj)
if len(cont) == 0:
return nav_list
else:
for ct in cont:
self.extract_item(ct, nav_list)
# nav_list.append(cont)
return nav_list
Здесь представлена рекурсивная версия проверки дочерних объектов запросов django.
Трюк заключался в том, чтобы передать через параметр balnk список и проверить, есть ли в кверисете объект больше нуля. Если результат равен нулю, то вернуть выполнение, вернув переданный список.
Однако, если есть объект, то он будет добавлять каждый объект в список и рекурсивно вызывать функцию и, наконец, возвращать полный список.
N.B: Проверка объекта с помощью len()
приведет к тому, что quryset будет повторно проверять базу данных. Вместо этого, поскольку django кэширует результат ORM, поэтому count()
будет использовать кэш и вычислять уже полученный результат.
def extract_item(self, nav_obj, nav_list: list):
"""
Recursively call and check if there is any child available.
"""
cont = Content.objects.filter(parent_id=nav_obj)
if len(cont) == 0:
return nav_list
else:
for ct in cont:
nav_list.append(ct)
self.extract_item(ct, nav_list)
return nav_list
def get_nav_items(self, instance):
"""
Get all the children for the model object
"""
childs = self.extract_item(instance, [])
menu_objecs = []
for item in childs:
menu_objecs.append(ContentNevItemSerializer(item).data)
return menu_objecs