#django
#django
Вопрос:
У меня есть модель django следующим образом:
class Person(models.Model):
name = models.CharField(max_length=255)
class Relationship(models.Model):
parent = models.ForeignKey(Person)
child = models.ForeignKey(Person)
description = models.TextField(blank=True)
На мой взгляд, я передаю определенного человека и отношения, в которых он / она является родителем:
person = Person.objects.filter(name ='some name')
descendant_relationships = Relationship.objects.filter(parent = person)
Я хочу показать потомков этого человека в списке в шаблоне:
<ul>
{% for item in descendant_relationships%}
<li> {{item.child.name}} - {{item.description}} </li>
{% endfor %}
</ul>
Но этот код шаблона не будет показывать дочерних элементов дочерних элементов (т. Е. внуков, правнуков и т.д.). Как я могу заставить отображаться этих потомков более низкого уровня? Я полагаю, что рекурсия где-то необходима, но где?
Ответ №1:
Сначала задайте связанное имя для вашего отношения ForeignKeys:
parent = models.ForeignKey(Person, related_name='child_relationships')
child = models.ForeignKey(Person, related_name='parent_relationships')
Затем добавьте что-то вроде следующего для вашего Person models.py:
def get_descendants(self):
descendants = []
children = [relationship.child for relationship in self.child_relationships.all()]
for child in children:
descendants = child.get_descendants()
return descendants
Вместо метода для возврата дочерних элементов мы можем адаптировать это для возврата отношений:
def get_descendant_relationships(self):
relationships = []
for child in self.child_relationships.all():
relationships = child.get_descendant_relationships()
return descendants
Комментарии:
1. Я реализовал вышеупомянутое. Однако это не позволит мне отобразить описание связи в моем шаблоне.
Ответ №2:
Если вам нужно только отношение «один ко многим» между родительским и дочерним элементами, вы можете удалить дополнительную таблицу:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', null=True, blank=True, related_name='a_name')
def genealogical_tree(self, type_of_members, generations):
"""
@generations: the number of generations to be traversed in the tree(
controls recursion)
"""
formated_members = {}
if generations:
if type_of_members == 'parent':
members = [self.parent]
elif type_of_members == 'children':
members = self._default_manager.filter(parent=self)
for member in members:
formated_members[member.name] = member.genealogical_tree(
type_of_members, generations-1)
return formated_members
Примеры:
from models import Person
f=Person(name='f')
s=Person(name='s')
gs=Person(name='granson')
gs.save()
s.save()
f.save()
s.parent=f
s.save()
gs.parent=s
gs.save()
f.genealogical_tree('children',1)
>>> {u's': {}}
f.genealogical_tree('children', 2)
>>> {u's': {u'granson': {}}}
gs.genealogical_tree('parent', 2)
>>> {'s': {'f': {}}}
gs.genealogical_tree('parent', 1)
>>> {'s': {}}